Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste


C - Programmierung am Raspberry  Schaltpläne und Bauteilbeschreibungen  Adapterkabel  Mechanik  EDV-Literatur deutsch 



    FIAN Österreich     Marktplatz Natur    
    Bäckerei Freitag

capt10

Kapitel zehn - Datei Ein- und Ausgabe

Lesen und Schreiben von Dateien

Im vorherigen Kapitel haben wir uns angesehen, wie Sie Eingaben vom Benutzer an der Konsole erhalten. In diesem Kapitel werden wir uns mit der anderen gängigen Methode zur Eingabe und Ausgabe in C befassen: Lesen und Schreiben von Dateien.

Viele Programme müssen auf Dateien auf der Festplatte des Host-Computers zugreifen können. Auch wenn nur Benutzereinstellungen und ähnliches gespeichert werden sollen, ist der Dateizugriff eine Grundvoraussetzung für viele Programmieraufgaben.

In C wird auf Dateien mit Hilfe von Datei-Pointern (file pointers) zugegriffen. Ein Datei-Pointer enthält alle Informationen, die für den Zugriff auf eine Datei erforderlich sind - sowohl den Namen als auch den Speicherort im Dateisystem und die aktuelle Position in der Datei, an der Daten gelesen oder geschrieben werden.

Das erste, was wir tun müssen, ist einen Datei-Pointer zu bekommen. Dies geschieht mit der C-Funktion fopen, die zwei Argumente akzeptiert. Das erste Argument ist der Pfad zur Datei, einschließlich Name und Erweiterung. Das zweite Argument wird als Dateizugriffsmodus (file access mode) bezeichnet. Dies ist ein Code, der angibt, ob Sie aus der Datei lesen oder in sie schreiben möchten.

Schauen wir uns ein Beispiel zum Lesen einer Datei an. Verwenden Sie Ihren Texteditor, um eine Datei mit dem Namen input.txt im Verzeichnis /home/pi auf Ihrem Pi zu erstellen, und geben Sie alles ein, was Sie möchten. Speichern Sie es und erstellen Sie das folgende Programm und führen Sie es aus:

#include <stdio.h>
 
void main (void)
  {
  FILE *fp;
  int value;
  fp = fopen ("/home/pi/input.txt", "rb");
  if (fp)
  {
    while (1)
  {
    value = fgetc (fp);
    if (value == EOF) break;
    else printf ("%c", value);
  }
  fclose (fp);
  }
}

Oben: Zum Lesen oder Schreiben einer Datei muss ein Datei-Ponter mit fopen geöffnet werden. Der resultierende Pointer wird dann in allen Vorgängen verwendet. Denken Sie daran, den Pointer anschließend mit fclose zu schließen.

[ÜBERPRÜFEN SIE IMMER IHREN DATEI POINTER]
Gehen Sie niemals davon aus, dass fopen funktioniert hat - überprüfen Sie immer, ob der zurückgegebene Wert ein gültiger Pointer ist (d.h. nicht NULL). Wenn Sie versuchen, von einem NULL Pointer zu lesen, erhalten Sie zufälligen Unsinn. Wenn Sie auf einen NULL Pointer schreiben, stürzt der Computer wahrscheinlich ab!

Zuerst deklarieren wir eine Datei-Pointer-Variable namens fp, die den Typ FILE * hat. Wir deklarieren auch eine Ganzzahl, die wir verwenden, um die aus der Datei eingelesenen Zeichen zu speichern.

Anschließend erstellen wir den Datei-Pointer mit dem Befehl fopen („file open“). Wir öffnen die Datei unter /home/pi/input.txt und setzen den Modus auf "rb", was „binär lesen“ („read binary“) anzeigt. Dadurch wird der Datei-Pointer erstellt und am Anfang der Datei initialisiert.

Wir prüfen dann, ob der Datei-Pointer nicht NULL ist. Wenn der Pointer als NULL zurückgegeben wird, wurde die Datei nicht erfolgreich geöffnet. Beim Lesen bedeutet dies normalerweise, dass die Datei nicht vorhanden ist.

Wenn der Datei-Pointer vorhanden ist, rufen wir die Funktion fgetc („file get character“) in einer Schleife auf. Bei jedem Aufruf dieser Funktion wird ein einzelnes Byte aus der Datei gelesen und der Datei-Pointer auf das nächste Byte in der Datei verschoben. Wenn der Datei-Pointer das Ende der Datei erreicht, gibt er den speziellen Wert EOF zurück („Dateiende“, „end of file“). Daher drucken wir den von fgetc zurückgegebenen Wert jedes Mal aus, bis EOF zurückgegeben wird.

Sobald wir die Datei gelesen haben, beenden wir den Zugriff darauf, indem wir fclose („file close“) aufrufen. Dadurch wird der Datei-Pointer freigegeben und Sie können ihn wieder verwenden, um auf eine andere Datei zuzugreifen.

Beachten Sie, dass fgetc beim Lesen von Zeichen eine Ganzzahl zurückgibt. Dies liegt daran, dass der Code für EOF außerhalb des gültigen Bereichs einer Zeichenvariablen (0 - 255) liegt. Sofern nicht am Ende einer Datei, gibt fgetc einen ganzzahligen Wert zurück, der immer als Zeichen behandelt werden kann.

[ERINNERN SIE SICH AN FCLOSE]
Es ist leicht zu vergessen, fclose in Ihrer Datei aufzurufen, aber es ist wichtig, dies zu tun. Auf einigen Systemen wird der Schreibvorgang beim Schreiben in das Dateisystem erst abgeschlossen, wenn fclose aufgerufen wird. Wenn Ihr Programm fclose nicht aufruft, stellen Sie möglicherweise fest, dass Sie in Dateien schreiben und nichts darin angezeigt wird.

Eine Datei schreiben

Um in eine Datei zu schreiben, verwenden wir einen Datei-Pointer genauso, öffnen ihn jedoch im Schreibmodus.

#include <stdio.h>
 
void main (void)
{
  FILE *fp;
  int value;
 
  fp = fopen ("/home/pi/output.txt", "wb");
 
  if (fp)
  {
    for (value = 48; value < 58; value++)
    {
      fputc (value, fp);
    }
  fclose (fp);
  }
}

In diesem Fall öffnen wir die Datei /home/pi/output.txt im Modus „wb“, der „write binary“ (binär schreiben) anzeigt. Dies öffnet die Datei zum Schreiben. Wenn diese Datei bereits vorhanden ist, wird der Inhalt gelöscht.

Wir rufen dann die Funktion fputc („file put character“) in einer Schleife auf und schreiben die Bytes 48, 49 … 57 in die Datei. (Dies sind die Zeichencodes für die Textzeichen für die 10 Ziffern 0, 1 … 9). Nach wie vor schließen wir dann den Datei-Pointer. Wenn Sie dies ausführen und dann in ihrem Home-Verzeichnis suchen, sollten Sie die Datei output.txt finden, die die Zeichenfolge 0123456789 enthält.

[LESEN UND SCHREIBEN SIE DIE GLEICHE DATEI]
Sie können eine Datei zum gleichzeitigen Lesen und Schreiben mit demselben Pointer öffnen. Stellen Sie den Dateizugriffs - Modus auf „rb+„, um eine vorhandene Datei zu lesen und zu überschreiben. Setzen Sie es auf „wb+„, um eine neue Datei zu erstellen und zurücklesen zu können, was Sie darin geschrieben haben. Setzen Sie es auf „ab+„, um eine Datei zu öffnen, die am Ende angehängt und daraus gelesen werden kann.

Formatierte Ausgabe

fputc ist nützlich, um Bytes in eine Datei zu schreiben, aber es ist eine unbequeme Methode, Text in eine Datei zu schreiben. Hierfür können wir die Funktion fprintf verwenden („file print formatted“).

#include <stdio.h>
 
void main (void)
{
  FILE *fp;
 
  fp = fopen ("/home/pi/output.txt", "wb");
 
  if (fp)
  {
    fprintf (fp, "Das ist ein Text.\n");
    fclose (fp);
  }
}

fprintf funktioniert genauso wie sprintf, aber das erste Argument ist eher ein Datei-Pointer als eine Zeichenfolge.

Eine Datei verschieben

Sehr oft möchten wir eine Datei nicht überschreiben, sondern nur am Ende hinzufügen. Öffnen Sie sie dazu mit fopen (“/home/pi/output.txt“, „ab“); - „ab“ bedeutet „append binary / Binär anhängen“. Wenn die Datei vorhanden ist, wird die Ausgabe nach dem vorhandenen Dateiinhalt hinzugefügt. Wenn die Datei nicht vorhanden ist, wird sie erstellt und die Ausgabe beginnt am Anfang.

Manchmal möchten wir beim Zugriff auf eine Datei nicht unbedingt am Anfang beginnen. Mit der Funktion fseek kann der Datei-Pointer innerhalb der Datei neu positioniert werden.

#include <stdio.h>
 
void main (void)
{
  FILE *fp;
  int value;
  fp = fopen ("/home/pi/input.txt", "rb");
  if (fp)
  {
    fseek (fp, 10, SEEK_CUR);
    while (1)
  {
  value = fgetc (fp);
  if (value == EOF) break;
  else printf ("%c", value);
  }
  fclose (fp);
  }
}

Die Zeile fseek (fp, 10, SEEK_CUR) bewegt den Datei-Pointer 10 Byte vorwärts von der aktuellen Position gesehen, sodass dieses Programm alle bis auf die ersten zehn Zeichen in der Datei druckt. Das erste Argument für fseek ist der Datei-Pointer. Der zweite ist der Versatz, um den sich der Pointer bewegen soll. Dies kann positiv oder negativ sein. Daher verschiebt fseek (fp, -5, SEEK_CUR) den Pointer 5 Bytes von der aktuellen Position zurück.

Mit dem dritten Argument für fseek können Sie eine Position relativ zum Dateianfang (SEEK_SET) oder zum Dateiende (SEEK_END) anstelle der aktuellen Position auswählen. fseek (fp, 12, SEEK_SET) positioniert den Pointer um 12 Bytes nach dem Dateianfang, während fseek (fp, -17, SEEK_END) ihn 17 Bytes vom Ende der Datei entfernt positioniert.


Zurück zum Inhalt    Vorige Seite    Nächste Seite

capt10.txt · Zuletzt geändert: 2020/10/29 10:46 von administrator