Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort
Vorwort des Gutachters
1 Einstieg in C
2 Das erste Programm
3 Grundlagen
4 Formatierte Ein-/Ausgabe mit »scanf()« und »printf()«
5 Basisdatentypen
6 Operatoren
7 Typumwandlung
8 Kontrollstrukturen
9 Funktionen
10 Präprozessor-Direktiven
11 Arrays
12 Zeiger (Pointer)
13 Kommandozeilenargumente
14 Dynamische Speicherverwaltung
15 Strukturen
16 Ein-/Ausgabe-Funktionen
17 Attribute von Dateien und das Arbeiten mit Verzeichnissen (nicht ANSI C)
18 Arbeiten mit variabel langen Argumentlisten – <stdarg.h>
19 Zeitroutinen
20 Weitere Headerdateien und ihre Funktionen (ANSI C)
21 Dynamische Datenstrukturen
22 Algorithmen
23 CGI mit C
24 MySQL und C
25 Netzwerkprogrammierung und Cross–Plattform-Entwicklung
26 Paralleles Rechnen
27 Sicheres Programmieren
28 Wie geht’s jetzt weiter?
A Operatoren
B Die C-Standard-Bibliothek
Stichwort

Buch bestellen
Ihre Meinung?

Spacer
<< zurück
C von A bis Z von Jürgen Wolf
Das umfassende Handbuch
Buch: C von A bis Z

C von A bis Z
3., aktualisierte und erweiterte Auflage, geb., mit CD und Referenzkarte
1.190 S., 39,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1411-7
Pfeil 16 Ein-/Ausgabe-Funktionen
Pfeil 16.1 Was ist eine Datei?
Pfeil 16.2 Formatierte und unformatierte Ein-/Ausgabe
Pfeil 16.3 Standard-Streams
Pfeil 16.4 Höhere Ein-/Ausgabe-Funktionen
Pfeil 16.5 Datei (Stream) öffnen – »fopen«
Pfeil 16.5.1 Modus für »fopen()«
Pfeil 16.5.2 Maximale Anzahl geöffneter Dateien – »FOPEN_MAX«
Pfeil 16.6 Zeichenweise lesen und schreiben – »getchar()« und »putchar()«
Pfeil 16.6.1 Ein etwas portableres »getch()«
Pfeil 16.7 Zeichenweise lesen und schreiben – »putc()«/»fputc()« und »getc()«/»fgetc()«
Pfeil 16.8 Datei (Stream) schließen – »fclose()«
Pfeil 16.9 Formatiertes Einlesen/Ausgeben von Streams mit »fprintf()« und »fscanf()«
Pfeil 16.10 Standard-Streams in C
Pfeil 16.10.1 Standard-Streams umleiten
Pfeil 16.11 Fehlerbehandlung von Streams – »feof()«, »ferror()« und »clearerr()«
Pfeil 16.12 Gelesenes Zeichen in die Eingabe zurückschieben – »ungetc()«
Pfeil 16.13 (Tastatur-)Puffer leeren – »fflush()«
Pfeil 16.14 Stream positionieren – »fseek()«, »rewind()« und »ftell()«
Pfeil 16.15 Stream positionieren – »fsetpos()«, »fgetpos()«
Pfeil 16.16 Zeilenweise Ein-/Ausgabe von Streams
Pfeil 16.16.1 Zeilenweise lesen mit »gets()«/»fgets()«
Pfeil 16.16.2 Zeilenweise schreiben mit »puts()«/»fputs()«
Pfeil 16.16.3 Zeilenweise vom Stream einlesen mit »getline()« (nicht ANSI C)
Pfeil 16.16.4 Rezepte für zeilenweises Einlesen und Ausgeben
Pfeil 16.17 Blockweise lesen und schreiben – »fread()« und »fwrite()«
Pfeil 16.17.1 Blockweise lesen – »fread()«
Pfeil 16.17.2 Blockweise schreiben – »fwrite()«
Pfeil 16.17.3 Big Endian und Little Endian
Pfeil 16.18 Datei (Stream) erneut öffnen – »freopen()«
Pfeil 16.19 Datei löschen oder umbenennen – »remove()« und »rename()«
Pfeil 16.19.1 remove()
Pfeil 16.19.2 rename()
Pfeil 16.20 Pufferung einstellen – »setbuf()« und »setvbuf()«
Pfeil 16.20.1 Die Funktion »setbuf()«
Pfeil 16.20.2 Die Funktion »setvbuf()«
Pfeil 16.21 Temporäre Dateien erzeugen – »tmpfile()« und »tmpnam()«
Pfeil 16.21.1 »mkstemp()« – sichere Alternative für Linux/UNIX (nicht ANSI C)
Pfeil 16.22 Fehlerbehandlung
Pfeil 16.22.1 Fehlerausgabe mit »perror()«
Pfeil 16.22.2 Fehlerausgabe mit »strerror()«
Pfeil 16.23 Formatiert in einen String schreiben und formatiert aus einem String lesen – »sscanf()« und »sprintf()«
Pfeil 16.24 Byte- und wide-orientierter Stream
Pfeil 16.25 Ein fortgeschrittenes Thema
Pfeil 16.26 Low-Level-Datei-I/O-Funktionen (nicht ANSI C)
Pfeil 16.26.1 Datei öffnen – »open()«
Pfeil 16.26.2 Datei schließen – »close()«
Pfeil 16.26.3 Datei erzeugen – »creat()«
Pfeil 16.26.4 Schreiben und Lesen – »write()« und »read()«
Pfeil 16.26.5 File-Deskriptor positionieren – »lseek()«
Pfeil 16.26.6 File-Deskriptor von einem Stream – »fileno()«
Pfeil 16.26.7 Stream von File-Deskriptor – »fdopen()«


Rheinwerk Computing - Zum Seitenanfang

16.5 Datei (Stream) öffnen – »fopen« Zur nächsten ÜberschriftZur vorigen Überschrift

Die Bearbeitung von Dateien erfolgt in C immer zeichenorientiert. Da Dateien zunächst nichts anderes sind als eine unstrukturierte Folge von Einzelzeichen, spielt es keine Rolle, mit welcher Art von Daten gearbeitet wird. Erst bei der Verarbeitung der Daten bekommen die Einzelzeichen eine Bedeutung und eine Struktur.

Zuerst soll eine einfache Textdatei zum Lesen geöffnet werden. Dabei gehen Sie folgendermaßen vor:

FILE *datei;
...
datei = fopen("textdatei.txt", "r");

Es wurde eine Textdatei mit dem Namen textdatei.txt geöffnet. Mithilfe des Zeigers datei vom Typ FILE wird dabei ein Lese-Stream zu dieser Textdatei eingerichtet. Die Syntax der Funktion fopen() lautet:

#include <stdio.h>

FILE *fopen( const char * restrict pfadname,
             const char * restrict modus);

Als Pfadangabe (pfadname) ist jeder zulässige String erlaubt. Sollten Sie unter einem Microsoft-Betriebssystem programmieren, kann auch eine Laufwerksangabe erfolgen. Die maximale Stringlänge für pfadname ist in der Konstante FILENAME_MAX deklariert, die sich ebenso in der Headerdatei <stdio.h> befindet. Mit modus geben Sie an, wie auf den Stream zugegriffen wird. Im Beispiel wurde der Modus "r" (für read) zum Lesen von der Datei verwendet. Auf die einzelnen möglichen Modi gehe ich gleich ein. Wenn beim Öffnen einer Datei alles planmäßig verlief, wird der FILE-Zeiger zurückgegeben. Bei einem Fehler erhalten Sie hingegen den NULL-Zeiger zurück.

Der FILE-Zeiger – es wird ja auch von einem FILE-Stream gesprochen – ist eine Struktur, die in der Headerdatei <stdio.h> deklariert ist. Diese Struktur beinhaltet alle Informationen, die für die höheren Datei-E/A-Funktionen benötigt werden, beispielsweise:

  • den Puffer – die Anfangsadresse, den aktuellen Zeiger, die Größe
  • den File-Deskriptor (mehr dazu bei den Funktionen der niedrigeren Ebene)
  • die Position des Schreib- oder Lesezeigers
  • die Fehler- und EOF-Flags

Natürlich können Sie auch mehrere Dateien auf einmal öffnen:

FILE *datei, *datei2;
...
// Datei textdatei.txt zum Lesen öffnen
datei = fopen("textdatei.txt", "r");

// Datei textdat2.txt zum Lesen öffnen
datei2 = fopen("textdat2.txt", "r");

Kommen wir jetzt zu einem ausführbaren Beispiel der Funktion fopen():

/* fopen1.c */
#include <stdio.h>
#include <stdlib.h>

int main(void) {
   FILE *datei;

   /* Bitte Pfad und Dateinamen anpassen */
   datei = fopen("test.txt", "r");
   if(NULL == datei) {
      printf("Konnte Datei \"test.txt\" nicht öffnen!\n");
      return EXIT_FAILURE;
   }
   return EXIT_SUCCESS;
}

Das Programm öffnet (falls vorhanden) die Datei test.txt. Konnte diese Datei nicht geöffnet werden bzw. ist sie nicht vorhanden, dann liefert die Funktion fopen() den NULL-Zeiger zurück. In diesem Beispiel muss sich die Datei test.txt im selben Verzeichnis befinden wie das ausführbare Programm. Liegt die Datei test.txt hingegen im Verzeichnis

C:\Dokumentationen\Texte\test.txt

dann muss das erste Argument in der Funktion fopen() folgendermaßen aussehen:

datei = fopen("c:\\Dokumentationen\\Texte\\test.txt", "r");

Bei Microsoft-Systemen müssen Sie darauf achten, dass statt nur einem Backslash zwei (\\) geschrieben werden, um das Zeichen '\' anzuzeigen. Bei Linux/UNIX ist das einfacher. Ist das Verzeichnis

/home/Texte/test.txt

dann muss sich Folgendes im ersten Argument befinden:

datei = fopen("/home/Texte/test.txt", "r");

Unter UNIX/Linux gibt es außerdem keine Laufwerksbezeichnung, da dort jedes Gerät – egal ob Festplatte, CD/DVD-ROM oder Diskette – als Datei betrachtet werden kann.


Hinweis

Bei den meisten Compilern unter MS-Windows kann mittlerweile die Pfadangabe ebenfalls mit einem einfachen Slash (c:/pfad/pfad) erfolgen – wie bei Linux/UNIX üblich.


Es gibt noch weitere Unterschiede zwischen diesen beiden Betriebssystemen. Tabelle 16.2 zeigt eine Gegenüberstellung von Linux/UNIX und Microsoft-Systemen.


Tabelle 16.2 Systemabhängiges bei der Angabe der zu öffnenden Datei

Eigenschaft Linux MS-Windows

Erlaubte Zeichen

alle Zeichen

Buchstaben, Zahlen und einige Sonderzeichen

Laufwerksbezeichnung

keine

A:, B:, C:, … Z:



Rheinwerk Computing - Zum Seitenanfang

16.5.1 Modus für »fopen()« Zur nächsten ÜberschriftZur vorigen Überschrift

Außer dem Lesezugriff ("r"), den Sie bereits verwendet haben, gibt es eine Reihe weiterer Zugriffsmöglichkeiten auf einen Stream. Tabelle 16.3 enthält einen Überblick über die vorhandenen Modi und deren Bedeutung.


Tabelle 16.3 Modus zum Öffnen einer Datei mit »fopen( )«

Modus Bedeutung
"r"

Öffnen einer Datei zum Lesen. Wenn die Datei nicht existiert oder nicht geöffnet werden konnte, gibt fopen() NULL zurück.

"w"

Anlegen einer Datei zum Ändern. Wenn die Datei nicht geändert werden kann bzw. wenn keine Schreibberechtigung besteht, liefert hier fopen() NULL zurück. Wenn unter Windows/MS-DOS die Datei ein Read-only-Attribut hat, kann sie nicht geöffnet werden.

"a"

Öffnet die Datei zum Schreiben oder zum Anhängen an das Ende der Datei. Wenn die Datei nicht vorhanden ist, liefert fopen() wieder NULL zurück. Auch NULL wird zurückgeliefert, wenn keine Zugriffsrechte bestehen.

"r+"

Öffnet die Datei zum Lesen und Schreiben, also zum Verändern. Bei Fehlern oder mangelnden Rechten liefert fopen() auch hier NULL zurück.

"w+"

Anlegen einer Datei zum Ändern. Existiert eine Datei mit gleichem Namen, wird diese zuvor gelöscht. Bei Fehlern oder mangelnden Rechten liefert fopen() hier NULL zurück.

"a+"

Öffnen einer Datei zum Lesen oder Schreiben am Ende der Datei. Falls noch keine Datei vorhanden ist, wird eine angelegt. Bei Fehlern oder mangelnden Rechten liefert fopen() NULL zurück.


Damit dieses Buch auch als Referenz zu gebrauchen ist, bietet Tabelle 16.4 eine schnellere Übersicht über die einzelnen Modi.


Tabelle 16.4 Schnellübersicht über die Bearbeitungsmodi

Bewirkt r w a r+ w+ a+

Datei ist lesbar.

x

x

x

x

Datei ist beschreibbar.

x

x

x

x

x

Datei ist nur am Dateiende beschreibbar.

x

x

Existierender Dateiinhalt geht verloren.

x

x



Hinweis

Wenn Sie unter Linux eine neue Datei mit dem Modus "w" oder "a" anlegen wollen, schreibt der POSIX-Standard vor, dass die Datei mit folgenden Rechten angelegt wird: -rw-rw-rw


An diese Modi können außerdem zwei weitere Zeichen angehängt werden, die zwischen Text- und Binärdateien unterscheiden (siehe Tabelle 16.5).


Tabelle 16.5 Text- und Binärmodus

Zusätzlicher Modus Bedeutung
b

Die Datei wird im Binärmodus geöffnet. Die Zeichen werden dabei nicht verändert bzw. konvertiert. Das heißt, jedes Zeichen wird so weitergegeben, wie es in der Datei steht, und es wird so in die Datei geschrieben, wie die Schreibfunktion eingestellt ist. Der Modus b wird bei Linux nicht verwendet und bei Angabe ignoriert. Er wird nur aus Kompatibilitätsgründen zu ANSI C beibehalten.

t

Die Datei wird im Textmodus geöffnet und sollte daher auch lesbare Textzeichen beinhalten.


Lassen Sie ich kurz den Unterschied zwischen Textdateien und Binärdateien erläutern: Textdateien sind für den Menschen mit einem Editor lesbar, wogegen Binärdateien bzw. binäre Zeichen (0,1) die Sprache bilden, die der Computer versteht. Für einen Menschen sind Binärdateien kaum lesbar. Daher bestehen Textdateien immer aus sichtbaren ASCII-Zeichen und ein paar Steuercodes, wie etwa Zeilenschaltungen oder Tabulatoren. Für die Bearbeitung reiner Textdateien ist der Modus t gedacht. Da bei MS-DOS ein Zeilenende mit der Sequenz \r\n angezeigt wird und bei Linux nur durch ein einzelnes \n, führen Compiler für MS-DOS/Windows im Textmodus t folgende Konvertierung durch:

  • Beim Schreiben in eine Textdatei wird ein \n automatisch in ein \r\n konvertiert.
  • Beim Lesen einer Textdatei wird ein \r\n in ein einzelnes \n konvertiert.
  • Beim Lesen einer Textdatei wird die Tastenkombination Taste Strg + Taste Z (unter MS-Windows/DOS) und Taste Strg + Taste D (unter Linux/UNIX) als Dateiende interpretiert und liefert automatisch EOF (End Of File).

Hinweis

Um die Anpassung müssen Sie sich als Programmierer allerdings nicht mehr direkt kümmern, weil dies von den Funktionen der Standard-Bibliothek vorgenommen wird.


Im Binärmodus wird diese Konvertierung nicht vorgenommen. Bei Linux/UNIX bedeutet das b nichts, wie in Tabelle 16.5 schon erwähnt wurde, und wird bei Verwendung ignoriert. Unter Linux wird außerdem jede Datei binär gespeichert.

Den Namen der zu öffnenden Datei können Sie natürlich auch mithilfe von Argumenten aus der Kommandozeile angeben. Ein Beispiel:

/* fopen2.c */
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
   FILE *datei;

   if(argc < 2) {
      printf("Verwendung : %s [datei_zum_Oeffnen]\n", *argv);
      return EXIT_FAILURE;
   }
   datei = fopen(argv[1], "r");
   if(datei != NULL)
      printf("Datei erfolgreich geöffnet\n");
   else {
      printf("Fehler beim Öffnen der Datei");
      return EXIT_FAILURE;
   }
   return EXIT_SUCCESS;
}

Zuerst wird überprüft, ob zwei Argumente in der Kommandozeile eingegeben wurden. Ist dies nicht der Fall, wird eine entsprechende Fehlermeldung ausgegeben. Ansonsten wird versucht, die Datei zu öffnen, die Sie in der Kommandozeile mit dem zweiten Argument angegeben haben. Tritt dabei ein Fehler auf, liegt dies meistens an einer falschen Pfadangabe oder unzureichenden Rechten einer Datei.


Rheinwerk Computing - Zum Seitenanfang

16.5.2 Maximale Anzahl geöffneter Dateien – »FOPEN_MAX« topZur vorigen Überschrift

Bei einem Programm, bei dem sehr viele Dateien gleichzeitig geöffnet werden, sollten Sie eine Überprüfung mit der Konstante FOPEN_MAX aus der Headerdatei <stdio.h> vornehmen. Diese Konstante legt fest, wie viele Dateien gleichzeitig pro Prozess geöffnet werden dürfen. Testen können Sie dies z. B. so:

/* fopen3.c */
#include <stdio.h>
#include <stdlib.h>

int main(void) {
   printf("Max. offene Dateien : %d\n",FOPEN_MAX);
   return EXIT_SUCCESS;
}

Hinweis für Fortgeschrittene

Laut ANSI C sollten Sie per fopen() mindestens acht Dateien mit einem Prozess öffnen können.

Meistens liegt dieser Wert aber weitaus höher. Außerdem sind mit acht Dateien reale Streams gemeint, also ohne die Standard-Streams stdin, stdout und stderr. Dies möchte ich für den Fall erwähnen, dass Sie die Struktur FILE tatsächlich auf die Anzahl offener Dateien überprüfen und sich wundern, warum dabei immer mehr Streams offen sind, als Sie in Wirklichkeit geöffnet haben.


Damit alles reibungslos mit dem erfolgreich zurückgegebenen Stream verläuft und Sie problemlos in Dateien schreiben bzw. aus diesen lesen können, müssen Sie bei der Anwendung der Funktion fopen() noch folgende Punkte berücksichtigen:

  • Fehlerflags und EOF-Flags werden beim Öffnen einer Datei zurückgesetzt.
  • Wollen Sie, nachdem Sie aus einem Stream gelesen haben, in diesen schreiben, so geht dies nur, wenn Sie vorher eine der folgenden Funktionen verwenden: fflush(), fsetpos(), fseek() oder rewind().
  • Wollen Sie aus einem Stream lesen, in den Sie zuvor geschrieben haben, dann müssen Sie eine der Funktionen fsetpos(), fseek() oder rewind() verwenden; außer es wurde das Dateiende (EOF) gelesen.

Machen Sie sich keine Sorgen, falls Sie diese Punkte noch nicht verstanden haben – Sie werden auf den nächsten Seiten aufgeklärt.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen. >> Zum Feedback-Formular
<< zurück
  
  Zum Katalog
Zum Katalog: C von A bis Z

 C von A bis Z
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: C/C++






 C/C++


Zum Katalog: Einstieg in C






 Einstieg in C


Zum Katalog: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Katalog: C++ Handbuch






 C++ Handbuch


Zum Katalog: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2009
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Rheinwerk Computing]

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de