FILE Problematik
-
ok habs mal so versucht aber er bringt beim fscanf ab:
while(fgets(buffer, 100, fz) != NULL) { buffer[strlen(buffer)-1]='\0'; fscanf(buffer, "%3.2lf %3.2lf %3.2lf %3.2lf %s", &x[k].re, &x[k].im, &x[k].r, &x[k].w_deg, &x[k].comment); k++; }
-
ist diese zeile notwendig?
buffer[strlen(buffer)-1]='\0';
normalerweise müssste es klappen
-
Diese Zeile dachte ich mir weil er ja aus der Datei formatiert liest.
am Ende einer Zeile steht in der Datei ein '\n' (und in wirklichkeit noch ein '\r' dazu) Ich dachte mir ich schließe den String ordentlich mit einer '\0' ab.folgende Fehlermeldung kommt egal ob ich die Zeile habe oder nicht
Unhandled exception at 0x00404285 in C.exe: 0xC0000005: Access violation reading location 0x30302e31.
-
BorisDieKlinge schrieb:
ist diese zeile notwendig?
buffer[strlen(buffer)-1]='\0';
Diese Zeile bewirkt im besten Fall gar nichts (sie sucht die Stringendemarkierung, und setzt dort eine Stringendemarkierung hin). Im schlimmsten Fall (wenn keine Stringendemarkierung da ist), bewirkt sie undefiniertes Verhalten.
JDHawk, lass den Quatsch mit "3.2". Diese Schreibweise gibt es nur für printf, nicht für scanf.
-
Diese Zeile bewirkt im besten Fall gar nichts (sie sucht die Stringendemarkierung, und setzt dort eine Stringendemarkierung hin). Im schlimmsten Fall (wenn keine Stringendemarkierung da ist), bewirkt sie undefiniertes Verhalten.
Sicher? fgets liest doch eine Zeile soweit wie man angegeben hat oder bis ein '\n' kommt. dann speichert er dieses '\n' mit in den String.
JDHawk, lass den Quatsch mit "3.2". Diese Schreibweise gibt es nur für printf, nicht für scanf.
[/quote]
Ich dachte mir bloß´wie soll das fscanf wissen wo ein Wert anfängt und der andere endet.
-
JDHawk schrieb:
Sicher? fgets liest doch eine Zeile soweit wie man angegeben hat oder bis ein '\n' kommt. dann speichert er dieses '\n' mit in den String.
Edit: Jetzt hab ich's kapiert. Du willst das \n abschneiden, nicht den String terminieren.
Ich dachte mir bloß´wie soll das fscanf wissen wo ein Wert anfängt und der andere endet.
An den Leerzeichen dazwischen.
-
ok geb mich geschlagen. klar, strlen berechnet die anzahl der char bis zum ende. im debug mode sehe ich da eine zahl 10 die für '\n' steht. vielleicht ist das das zeichen für strlen das hier der string endet.
aber ist auch egal.
Er bringt trotzdem den fehler. fscanf erwartet doch als erstes parameter ein FILE*
ich gebe ihm ein char*. Ist das vielleicht das problem?
-
JDHawk schrieb:
ok geb mich geschlagen.
Ich hatte dich falsch verstanden.
JDHawk schrieb:
Er bringt trotzdem den fehler. fscanf erwartet doch als erstes parameter ein FILE*
ich gebe ihm ein char*. Ist das vielleicht das problem?Wenn du aus einem Puffer einliest, musst du sscanf benutzen.
-
Ok habe nun zwei Varianten die klappen, ausser das er das EOF in der Datei nicht findet. Keine Ahnung wieso.
Variante eins: Direkt aus dem Stream (Datei) in die Var. schreiben:
while(1) { //buffer[strlen(buffer)-1]='\0'; if(!(fscanf(fz, "%lf %lf %lf %lf %s", &x[k].re, &x[k].im, &x[k].r, &x[k].w_deg, &x[k].comment))) break; else k++; }
Variante zwei: Zuerst aus Stream (Datei) in buffer lesen und dann in Var
while(fgets(buffer, 100, fz)!=EOF) { sscanf(buffer,"%lf %lf %lf %lf %s", &x[k].re, &x[k].im, &x[k].r, &x[k].w_deg, &x[k].comment); k++; }
beides klappt nun wunderbar aber er hört nicht auf. bzw. er findet das EOF nicht
-
Du hast die Rückgabewerte durcheinandergeworfen. fscanf gibt im am Ende EOF zurück, fgets NULL. Dein Code scheint davon auszugehen, dass es andersherum ist.
-
fgets() liefert einen char * zurück, d.h. du mußt auf NULL abfragen. (EOF ist meistens als -1 definiert)
Aber fscanf() liefert die Anzahl der gelesenen Zeichen zurück und dabei dan EOF im Fehlerfall.
Du hast es also genau verkehrt herum gemacht.
Hast du denn keine Hilfe der C-Standard-Bibliothek?
-
Doch schon die Hilfe von MS Visual Studio, aber da steht ja auch nicht ob z.b. strlen() auch bei '\n' aufhört zu zählen.
-
JDHawk schrieb:
Doch schon die Hilfe von MS Visual Studio, aber da steht ja auch nicht ob z.b. strlen() auch bei '\n' aufhört zu zählen.
weil '\n' für die Länge einer Zeichenkette keine Rolle spielt sondern, wo (bzw. wann) '\0' vorkommt. Sonst hieße es linelen()
-
ok jetzt weis ich wo die Problematik war:
nach fgets() steht in buffer eine Zeile inklusive einem '\n' als vorletzter char. Erst danach kommt ein '\0'.
mit buffer[strlen(buffer)-1]='\0' wird dieses '\n' mit '\0' überschrieben.
Also ist die Länge dann um eins kleiner.Das muss man wissen, sonst gibt er bei der ausgabe ein '\n' aus und dann wundert man sich wo die leerzeile herkommt.
-
hättest du die Doku von fgets genauer gelesen, wärst du selber drauf gekommen
man fgets schrieb:
fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A '\0' is stored after the last character in the buffer.