while(!feof(fp)) wiederholt letzte Zeile der Datei (Programmieren in C)?

mjutu  03.12.2020, 15:45

Veröffentliche nicht deinen Namen im Internet.

Nico3010 
Beitragsersteller
 03.12.2020, 15:50

Wieso?


3 Antworten

Allerdings wird bei mir die letzte Zeile zwei mal eingelesen.

Nein, wird sie nicht. Sie wird 2 mal ausgegeben. Das ist etwas grundlegend anderes. Und zwar liest FSCANFdie letzte Zeile ein und die wird wohl mit einem Zeilenumbruch beendet, oder? Dann ist aber noch nicht das Fileende überschritten. In der nächsten Iteration liest FSCANF 0 Zeichen ein und speichert sie in Line. Darum belibt Line auch gleich.

Der Code enthält einige ernste Probleme:

  • Ungenutzte Variablen "Speicher" und "Baum"
  • Kein Test ob das Öffnen des Files erfolgreich war.
  • FSCANF lässt das Programm crashen, wenn die Zeile länger ist als die Variable Line.
  • Output von FSCANF wird nicht abgefangen - das hätte das Problem wohl schneller gelöst.
  • fp wird nicht explizit geschlossen.

mjutu  03.12.2020, 16:04

Noch zum Namen: Du hast Aufgabenblätter hier veröffentlich. Hattest du eine Genehmigung dafür, denn die Dozenten haben das Urheberrecht daran. Theoretisch könnte man das also anzeigen und dir Ärger machen - oder dich mit der Androhung unter Druck setzen.

Zur Zeit ist das alles ziemlich pillepalle. Aber je mehr Daten man von sich preisgibt, desto tückischer wird es. Wenn du in 40 Jahren mal Bundeskanzler wirst und irgendwelche Deppen hauen dir deine alten Posts auf GuteFrage um die Ohren, nervt das. Wenn man nicht weiß, wie du heißt, erübrigt sich das Problem.

0
Nico3010 
Beitragsersteller
 03.12.2020, 15:59

Danke schonmal, Also

-Die Variablen brauche ich jetzt im folgenden, wollte aber erstmal schauen ob die while Schleife funktionier

-Den Test wegen des Öffnen der File hatte ich bereits gemacht, danach wieder rausgenommen (Ich nehme mal an es wäre trotzdem besser den immer drin zu lassen)

-Das stimmt, allerdings ist bekannt, dass jede Zeile kleiner ist (wie würde man das denn für eine unbestimmte menge machen?)

-Was ist mit der Output wird nicht abgefangen gemeint?

-das hatte ich vergessen

0

Du berücksichtigst den Rückgabewert von fscanf() nicht. Ich habe gerade keine Zeit, um es zu testen, aber hier ist, was (IMHO) passiert. Du rufst scanf() auf und die letzte Zeile wird gelesen. scanf stoppt beim Newline, weil Whitespace.

Somit bist Du aber am Ende der Datei angekommen, aber EOF wurde noch nicht signalisiert, weil kein Versuch unternommen wurde am Ende der Datei nochmal zu lesen. D.h. Dein fscanf wird ein weiteres mal aufgerufen, die Rückgabe wäre eine leere Zeile, weil jetzt aber ein EOF auftritt, bricht fscanf ab, setzt EOF (und gibt es auch entsprechend zurück). Der Puffer bleibt unangetastet und DU gibt ihn nochmals aus.

 if (fscanf(fp, "%s", &Line) == 1) printf("%s \n", Line);

So sollte die wiederholte Ausgabe für den EOF Fall unterdrückt werden.

Besser wäre natürlich eine ordentliche Auswertung der Rückgabe, um generell Fehler zu behandeln.


Nico3010 
Beitragsersteller
 03.12.2020, 16:02

Vielen Dank, so sieht es schon besser aus

0

fscanf("%s", Line) versucht, etwas zu lesen. Wenn das Dateiende schon erreicht wurde, bleibt Line unverändert.

Line enthält nur dann einen neuen String, wenn fscanf() 1 zurückgibt.

Deine Schleife wird so robuster:

while (1==fscanf(fp, "%s", &Line))
  printf("%s \n", Line);

Übrigens liest Du damit nur nacheinander alle Wörter ohne Leerzeichen. Zum Lesen von ganzen Zeilen gibt es die Funktion fgets():

while (fgets(Line, fp, sizeof Line))
  printf("%s", Line); // oder kürzer: puts(Line);