# Problem mit fgets [C++]



## Puepue (13. Juni 2010)

Ich habe eine Frage zu fgets
Ich möchte gerne eine mehrzeilige Datei auslesen und den Inhalt in einer Variablen speichern.

Also beispielsweise

```
Hallo Du,
wie geht es dir so?
Mir geht es gut, weil alles klappt und ich anfangen kann zu testen!
JUHU!
```

Wenn ich jetzt 

```
inhalt = strtok (inhalt,"\n");
			do {
				c = fgetc (pFile);
				fgets (inhalt , lenght+1 , pFile);
		   } while (c != EOF);
```
mache, dann bekomme ich in inhalt nur ein "UHU!" raus.

Wenn ich das ganze etwas anders versuche

```
inhalt = strtok (inhalt,"\n");
			for (int i = 0; i<(lenght); i++)
			{
				inhalt[i] = fgetc (pFile);
			}
```
Bekomme ich den gesamten Text +13 Zeichen Datenmüll ausgegeben. Wenn ich die Länge-13 setze, wird der Text schon vorm Ende mit Datenmüll ersetzt. 
Mit der Lösung mit Datenmüll am Ende könnte ich zwar leben, aber schön ist es halt nicht...


----------



## boerigard (13. Juni 2010)

Erstmal zu strtok. strtok zerlegt einen C-String in Tokens. Der C-String muss aber schon "gefüllt" sein. Du lässt strtok ja bereits auf "inhalt" los, obwohl du noch gar nicht die Datei gelesen hast. Also den Aufruf von strtok streichen. Und strtok ist eh nicht ganz ungefährlich, daher würde ich auch in Zukunft von der Funktion Abstand nehmen.

Dann zu fgetc: Das liest ein Zeichen aus dem Eingabestrom.
fgets: Liest so lange, bis es auf '\n\ (Zeilenumbruch) trifft und schreibt alles bis einschließlich '\n' in eine C-String Variable. Es liest quasi immer eine Zeile.

Weiter zu deinen Lösungen:

```
do {
    c = fgetc (pFile); //<- liest 'H' aus der Datei
    fgets (inhalt , lenght+1 , pFile); //<- liest "allo Du,\n" aus und schreibt es in inhalt.
} while (c != EOF);
```
Im nächsten Durchgang liest fgetc 'w' aus und fgets liest "wie geht es dir so?\n" aus und schreibt es in inhalt. Überschreibt dabei auch wieder "allo D,\n".
Im nächsten Durchgang wieder das gleich. Verstehst du, warum am Ende nur "UHU!" in inhalt steht?

Wo kommt eigentlich lenght her? Und wie ist eigentlich inhalt definiert? Hat inhalt eine feste Größe (char inhalt[GROSSE_ZAHL]) oder legst du inhalt dynamisch zur Laufzeit fest, abhängig von der Dateigröße? Über length?

Ich nehme das mal an. Also zur zweiten Lösung. Die ist schon nah dran. Der Datenmüll kommt daher, dass ganz am Ende deines C-String inhalt keine NULL steht. Du weißt, am Ende eines C-Strings muss immer eine abschließende NULL stehen, sonst gibt er bei der Ausgabe solange weiter aus, bis er auf eine NULL trifft. Und so lange gibt er eben Datenmüll aus.

Ok. wir machen jetzt eine Lösung aus den besten Teilen deiner beiden Lösungen. Du liest immer ein Zeichen (mit fgetc) aus prüfst ob du am EOF bist. Und gleichzeitig lässt du noch einen Iterator i hochzählen, damit wir wissen an welcher Stelle wir sind.

```
int c;
int i = 0; 
while((c = fgetc(pFile)) != EOF)
{
   inhalt[i] = c;
    i++;
}
inhalt[i] = 0; //<- Hier setzen wir die NULL
```

Achso, wenn du inhalt dynamisch, abhängig von der Filelength machst, dann denk an ein Extrazeichen Platz für die NULL.


----------

