Ich habe angefangen, etwas C als Hobby zu lernen und habe FILE seit geraumer Zeit blind als Deklaration für Dateizeiger verwendet, und ich habe mich gewundert. Ist dies ein Schlüsselwort oder ein spezieller Datentyp, mit dem C Dateien verarbeiten kann? Enthält es einen Stream zur darin enthaltenen Datei und andere Daten? Warum ist es als Zeiger definiert?
Ein Beispiel, um zu zeigen, was ich meine, um es etwas klarer zu machen:
FILE* fp; //<-- this
fp = fopen("datum.txt", "r");
while(!feof(fp)) {
// etc.
}
Beachten Sie, dass !feof(stream) ist immer falsch.
– pmg
10. Mai 2017 um 11:43 Uhr
Alexander
Ist dies ein Schlüsselwort oder ein spezieller Datentyp, mit dem C Dateien verarbeiten kann?
Worauf Sie sich beziehen, ist eine typdefinierte Struktur, die von der Standard-IO-Bibliothek verwendet wird, um die entsprechenden Daten für die Verwendung von fopen und seiner Funktionsfamilie zu speichern.
Warum ist es als Zeiger definiert?
Mit einem Zeiger auf eine Struktur können Sie diese dann als Parameter an eine Funktion übergeben. Dies ist beispielsweise das, was fgets oder fgetc in Form von akzeptieren function(FILE* fp)
Die fopen-Funktion gibt einen Zeiger auf eine neu erstellte FILE-Struktur zurück. Wenn Sie diesen neuen Zeiger Ihrer unbenutzten zuweisen, werden sie auf dasselbe verweisen.
Enthält es einen Stream zur darin enthaltenen Datei und andere Daten?
Die Strukturdefinition erscheint etwas illusorischer als ihre Beschreibung. Dies stammt direkt aus meiner stdio.h, aus MinGW32 5.1.4
typedef struct _iobuf
{
char* _ptr;
int _cnt;
char* _base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char* _tmpfname;
} FILE;
Dazu gehört auch der nette Kommentar davor:
Einige glauben, dass niemand, der bei klarem Verstand ist, die Interna dieser Struktur nutzen sollte.
Der Inhalt dieser Struktur scheint sich bei anderen Implementierungen stark zu ändern, die Glibc-Quellen haben normalerweise irgendeine Form von Kommentaren, aber ihre Struktur dafür ist unter viel Code begraben.
Es wäre sinnvoll, die oben genannte Warnung zu beachten und sich einfach keine Gedanken darüber zu machen, was sie bewirkt. 🙂
Meine erste Frage und eine großartige Antwort. Vielen Dank für Ihren Beitrag! Das klärt tatsächlich einiges auf.
– johnholtsdater
15. April 2011 um 6:11 Uhr
Sie brauchen keinen Zeiger, um zu übergeben struct um. Der Grund, warum es ein Zeiger ist, besteht darin, die Struktur zu verbergen. Es ist der C-Weg der Implementierung private Klassenmitglieder. Dies ist genau so, dass niemand versuchen würde, die Struktur selbst zu verwenden, da der Standard die Struktur nicht definiert, sondern nur einen Zeiger darauf benötigt. Wie bereits erwähnt – es heißt an undurchsichtig Typ.
– wenig adv
15. April 2011 um 6:16 Uhr
@littleadv Ich frage mich, welche der beiden Aussagen über die tatsächlich zutrifft FILE im Standard vorhanden sein. Wie auch immer, was wäre der Grund für die Erwähnung FILE Zeiger, definiert aber nicht, was es eigentlich ist/wie verhält es sich? Scheint seltsam, als würde man eine Funktion aus einem Header verwenden, ohne dass der Header irgendwo verfügbar ist?
– Peter Badida
13. Mai 2017 um 11:37 Uhr
Ich habe 20 Minuten lang in meinem GCC-Verzeichnis nach dieser Strukturdefinition gesucht und bin den Server meiner Universität durchgegangen, auf dem wir C-Projekte ausführen. Ich habe stdio.h auf beiden gefunden (interessanterweise waren beide nicht im eigentlichen GCC-Verzeichnis), und keiner hatte eine Definition für diese Struktur. Irgendwelche Hinweise darauf, wo sie auf RedHat- und Mint-Betriebssystemen zu finden sind?
– Ungeheuer
17. November 2017 um 2:14 Uhr
@littleadv Pointer macht den Typ nicht undurchsichtig. Um es undurchsichtig zu machen, sollte es auf void* gegossen werden. Worüber Sie sprechen, ist die Fähigkeit, unvollständige Typen zu verwenden, was tatsächlich eine Fähigkeit ist, die Zeiger zulassen. Wenn jedoch die interne Definition des Typs FILE in den Standardheadern bereitgestellt wird, bietet die Verwendung von Zeigern keine Deckkraft.
– SomeWittyBenutzername
8. April 2018 um 7:22 Uhr
Jens
FILE ist ein Bezeichner, der als Typedef-Name verwendet wird, normalerweise für a struct. Die stdio-Bibliothek hat normalerweise so etwas wie
typedef struct {
...
} FILE;
irgendwo. Alle stdio-Funktionen, die sich mit FILE-Zeigern befassen, kennen den Inhalt von ... und kann auf die Strukturmitglieder zugreifen. Die C-Programmierer müssen Funktionen wie verwenden fopen, feof, ferror, ungetc usw. zum Erstellen und Bearbeiten von DATEI-Strukturen. Solche Typen werden genannt undurchsichtig (dh Sie können nicht hineinsehen, sondern müssen Zugriffsfunktionen verwenden).
Warum ist es als Zeiger definiert?
Es ist nicht. Es ist eine Struktur, zu der dein code deklariert einen Zeiger. Beachten Sie das Sternchen in Ihrer
FILE* fp;
Dies ist ein weiteres Beispiel dafür, warum das Sternchen zum Variablenbezeichner gehören sollte, nicht zum Typnamen:
FILE *fp;
Das macht mehr Sinn, ich hatte vorher überhaupt nicht gewusst, was undurchsichtige Typen sind. Vielen Dank!
– johnholtsdater
15. April 2011 um 6:12 Uhr
Ich sehe das Argument nicht, das Sternchen mit dem Variablenbezeichner zu platzieren.
– IS4
25. April 2018 um 9:37 Uhr
@IllidanS4 Überlege FILE* fp1, fp2; Es sieht aus als ob fp1 und fp2 vom gleichen Typ wären, aber sie sind es nicht. Es ist eine trügerische Erklärung.
– Jens
25. April 2018 um 12:06 Uhr
Ja, das ist ein gültiges Argument, aber es wurde nicht durch das ursprüngliche Beispiel impliziert.
– IS4
26. April 2018 um 14:08 Uhr
Es ist kein Schlüsselwort, sondern ein Datentyp, der im ANSI-C-Standard definiert ist, um mit Dateien zu arbeiten. Es zeigt normalerweise auf eine interne Struktur, die die Datei und ihren aktuellen Zustand für die Bibliotheksfunktionen beschreibt.
Es ist ein spezieller Datentyp. Es enthält ein Dateihandle sowie verschiedene Flags, die intern von den verschiedenen stdio-Aufrufen verwendet werden. Sie müssen nie wirklich wissen, was darin enthalten ist, nur dass es sich um einen Datentyp handelt, den Sie herumreichen können.
Beachten Sie, dass
!feof(stream)
ist immer falsch.– pmg
10. Mai 2017 um 11:43 Uhr