Warum fuktioniert diese Schleife?
-
Hi
ich lerne gerade C mit Hilfe eines Buches. Dort wird unter anderem dieses Beispiel gezeigt, doch ich verstehe die funktionsweise nicht ganz:
while(fgets(puffer,MAX_STRING,stream)!=NULL){ printf("%s",puffer); ch=fgetc(stdin); fseek(stdin,0L,SEEK_END);
(Bei diesem Programm wird eine Datai eingelesen und wenn man Enter drückt wird die nächste Zeile angezeigt. Diese Schleife dient dazu die nächste Zeile anzuzeigen wenn man ENTER drückt)
Wie funktioniert diese Schleife?
Eigentlich müßte sie doch ewig laufen, da das Ende der Datei (sodass fgets NULL zurückliefert)nie erreciht wird.Ähnlich verhällt es sich bei diesem Beispiel:
while(!feof(ein)){ fputc(ch,aus); ch=fgetc(ein);
Auch hier müßte die Schleife doch eigentlich ewig laufen.
Vielleicht könntet ihr mir das erklären.
Vielen Dank.
-
wieso sollte das Ende der Datei nie erreicht werden?
-
while(fgets(puffer,MAX_STRING,stream)!=NULL)
while(!feof(ein))
Die Schleife läuft, so lange die Bedingung im Schleifenkopf erfüllt sind.
Bei der ersten Schleife gibt die funktion fgets() einen Zeiger auf den
gelesenen String zurück. Ist dieser NULL, also am ende des streams, wird die
Schleife abgebrochen. Es müsste eine unendlich große Datei sein, das daraus
eine Endlosschleife werden würde.Bei der zweiten Schleife gibt die funktion feof() 0 zurück, solange nicht
EOF, also das Ende der Datei erreicht ist. Mit einem ! wird der Rückgabe-
wert zu 1 und somit wird die Schleife durchlaufen.b4sh0r
-
Aber beim ersten Beispiel bleibt doch der Inhalt von Puffer bei jedem durchlauf gleich, da stream sich nicht verändert und auch sonst nichts weitergezählt wird.
Und bei der zweiten Schleife bleibt doch <ein> auch immer gleich.
Ich verstehs nicht.
-
Doch, die Einlesefunktionen (gets,getc usw.) bewegen jedesmal den (internen) Dateizeiger weiter. Um soviel Zeichen wie eingelesen wurde.
-
Das erklärt die zweite schleife aber wie funktioniert die erste: Was bewirkt das stdin bei fgets?
-
beim öffnen einer shell oder commandline werden vom betriebssystem standartmäßig
3 Filediskriptoren geöffnet.0 stdin
1 stdout
2 stderrstdin steht hier für die Eingabe auf der kommandozeile, also fgetc(stdin) ließt
zeichenweise von der Standarteingabe.Gib mal den ganzen code, nicht nur die halbe schleife!
-
mxpower schrieb:
Das erklärt die zweite schleife aber wie funktioniert die erste: Was bewirkt das stdin bei fgets?
Mit Einlesefunktionen meine ich auch die fget*-Funktionen.
Das fgetc(stdin) hat mit dem Datei-Einlesen nichts zu tun, das ist für's Enter-Drücken.
-
#include <stdio.h> #include <stdlib.h> #define MAX_STRING 81 main(int argc, char *argv[]){ FILE *stream; char puffer[MAX_STRING]; int ch; if(argc<2){ printf("\nAufruf: bspl077 <dateiname>\n"); exit(1); } if((stream=fopen(argv[1],"r"))==NULL){ printf("\n'%s': Oeffnungsfehler!\n",argv[1]); exit(1); } while(fgets(puffer,MAX_STRING,stream)!=NULL){ printf("%s",puffer); ch=fgetc(stdin); switch(ch){ case'a': case'A': fseek(stream,0L,SEEK_SET); break; case 27: goto ende; } fseek(stdin,0L,SEEK_END); } ende: fclose(stream); }
-
Wozu ist dann diese Zeile:
fseek(stdin,0L,SEEK_END);
?
-
fseek
Prototyp : int fseek(FILE *stream,long offset,int whence);
Header : <stdio.h>Beschreibung :
fseek setzt den zu stream gehörenden Dateizeiger auf die neue Position, die offset Bytes von der durch whence angegebenen Dateiposition entfernt ist. Für Streams im Textmodus sollte offset 0 sein oder ein Wert, der von ftell geliefert wurde. Die Art der Positionierung wird über drei in stdio.h definierte Konstanten für whence festgelegt:Konstante whence Dateiposition
SEEK_SET 0 Relativ zum Dateianfang
SEEK_CUR 1 Relativ zur aktuellen Position
SEEK_END 2 Relativ zum DateiendeBenutzen Sie fseek für Stream-Ein-/Ausgabe und lseek für Datei-Handle-Ein-/Ausgabe. In Dateien, die für Lese- und Schreiboperationen geöffnet worden sind, kann nach fseek zwischen "Lesen" und "Schreiben" gewechselt werden.
Rückgabewert :
fseek liefert bei fehlerfreier Ausführung den Wert 0 zurück, ansonsten einen Wert ungleich Null. Es ist möglich, daß fseek 0 zurückliefert, obwohl bei der Ausführung der Funktion ein Fehler aufgetreten ist. Dies liegt daran, daß der Zeiger letztendlich von DOS gesetzt und das Ergebnis der Positionierung nicht überprüft wird. fseek gibt nur für ungeöffnete Dateien oder Geräte einen Fehlercode zurück.
-
Aber was macht fseek in diesem Fall? Auf was zeigt denn stdin(in diesem Fall wohl nicht auf die Tastatur)?
Sorry wenn ich mich nen bischen blöd anstell aber ich blick da nich durch.
-
mxpower schrieb:
Aber was macht fseek in diesem Fall? Auf was zeigt denn stdin(in diesem Fall wohl nicht auf die Tastatur)?
Sorry wenn ich mich nen bischen blöd anstell aber ich blick da nich durch.Doch, im Normalfall zeigt stdin auf die Tastatur bzw. auf den Eingabepuffer der Tastatur. Und damit wird wohl versucht den internen Zeiger auf die letzte Stelle zu setzen, damit beim nächsten Einlesen nicht der Rest, der noch im Puffer stand, gleich übernommen wird.
-
die erklärung klingt gut, damit hat sich mein problem erledigt.
ich dank euch vielmals