das Ding nennt sich Webconverter und soll eigentlich nur z.B. ne
Webseite in ein Char Array "konvertieren". Macht also am Ende
Anführungszeichen und Zeilenumbrüche, bla... Nun hab ich das mit dem gcc
übersetzt und da kam am Ende(bei Ausführung) immer sowas raus:
>>>>>"ÿ\r\n"};<<<<<
Das stand dann am Ende des erzeugten Arrays. Kann man das irgendwie
erklären? Es hat ne Weile gedauert, bis ich raus hatte, dass es in C++
übersetzt werden sollte, dann gibt es dies komischen Probleme nicht, die
besagte Zeile sieht dann so aus: >>>>>"\r\n"};<<<<<
Hat irgendjemand von euch eine Ahnung wo plötzlich das ÿ(0xFF) her
kommt? Hat cpp nen anderen Zeichensatz? Also es ist jetzt nicht sofort
wichtig das zu wissen, aber es interessiert mich schon sehr, weil ich
bisher dachte, das gcc und g++ bei reinem C Code gleich handeln(vll.
stimmt aber auch meine Unterscheidung nicht).
Zu guter Letzt, auch wenns echt richtige PillePalle ist noch meine
Änderung:
is halt dafür gedacht die Arrays umzubenennen, wie gesagt Quatsch, aber
vll hilfts ja nem NOOB, zumindest gibts den kompletten Code des Files
IMHO bei Google nur einmal....
Danke für eure Antworten!
Ist eher Zufall, dass das mit dem C++ Compiler geklappt
hat.
Der Fehler ist in beiden Fällen, die fehlerhafte eof() Behandlung.
Merk dir folgende 2 Sätze:
"C und C++ versuchen nicht in die Zukunft zu schauen. Ob eine
Datei zu ende ist, kann erst festgestellt werden, nachdem ein
Leseversuch gestartet wurde und dieser Versuch fehlgeschlagen ist".
Die korrekte Art, in beiden Sprachen, eine Date zu lesen, besteht
immer darin, die Leseschleife auf dem Returnwert der Lesefunktion
aufzubauen. Dazu haben ausnahmslos alle Lesefunktionen sowohl
in C als auch in C++ einen Returnwert der sich dafür eignet.
feof() ist nicht dafür gedacht, die Leseschleife zu steuern,
sondern wird im Anschluss an die Leseschleife benutzt um fest-
zustellen, warum die Leseschleife abgebrochen wurde. Die Lese-
schleife bricht, aufgrund des Returnwertes der Leseoperation,
irgendwann ab. War dies, weil eof aufgetreten ist, dann ist alles
gut: Die Datei konnte fehlerfrei und vollständig gelesen werden.
Das Schema ist also immer
while( Leseoperation ) {
verabeite das Gelesene
}
if( !feof( ... ) ) {
melde einen fehler und gegebenenfalls
ein return
}
eventuell noch mit dem gelesenen etwas machen.
Dein Job ist es jetzt, rauszufinden welcher spezielle
Returnwert von fgetc kommt, um anzuzeigen, dass die
Leseoperation nicht geklappt hat. Hinweis: Es hat damit
zu tun, dass der Returnwert von fegtc wieder erwarten kein
char oder unsigned char sondern ein int ist.
Und ja, die 0xFF haben damit zu tun.
PS: Den obigen Fehler findet man sehr häufig. Sogar in Lehrbüchern.
Was die feof() Schleife auch nicht richtiger macht. Die klassische
Frage, die in Newsgroups dann normalerweise auftaucht, lautet
dazu: Warum wird mein letzter Datensatz doppelt verarbeitet?
Danke erst mal für deine Antwort.
Der Returnwert von fgetc() ist -1, weil das Dateiende erreicht ist. Die
Fkt. feof() ist ja aber scheinbar nur dafür da, zu unterscheiden, warum
die Datei nicht gelesen werden konnte, also ob wirklich das Ende
erreicht wurde oder ein anderer Fehler auftrat. Ich hab mir deinen Post
hier: Beitrag "Datei einlesen mit C" noch mal durchgelesen.
Hab mal n bissel rum gespielt. Also mit feof() könnte man es eigentlich
so machen:
1
while(1){
2
InChar=fgetc(*FILE);
3
if(feof(*FILE))
4
break;
5
6
//....Verarbeitung....
7
}
Dann bleibt die Geschichte aber hängen, wenn ein anderer Fehler
auftritt. Also macht:
1
while((InChar=fgetc(*FILE))!=EOF){
2
// ....Verarbeitung....
3
}
4
//Test ob Abbruch wegen Dateiende
5
if(!feof)
6
printf("Datei konnte nicht richtig eingelesen werden...");
wohl mehr Sinn. Zumindest wenn ich das richtig verstanden hab. Also war
mein Fehler, dass im Prinzip die letzte -1 auch noch geschrieben wurde,
oder?
Es ist übrigens wirklich so, dass ich bei mehreren Beispielen im Netz
den Test mit while(!feof()){...} gefunden hab. Naja, auf jeden Fall
klappt es jetzt auch mit gcc, warum die Geschichte mit g++ funktioniert
hat bleibt damit immer noch offen, aber das muss man wohl akzeptieren...
Icke Muster wrote:
> Der Returnwert von fgetc() ist -1, weil das Dateiende erreicht ist.
Exakt. Das Makro EOF, welches diese -1 kapselt hast du ja anscheinend
auch gefunden.
> Die> Fkt. feof() ist ja aber scheinbar nur dafür da, zu unterscheiden, warum> die Datei nicht gelesen werden konnte, also ob wirklich das Ende> erreicht wurde oder ein anderer Fehler auftrat.
Ganz genau.
Die Geschichte von C ist voller Missverständnisse :-)
> Ich hab mir deinen Post> hier: Beitrag "Datei einlesen mit C" noch mal durchgelesen.> Hab mal n bissel rum gespielt. Also mit feof() könnte man es eigentlich> so machen:>
1
>while(1){
2
>InChar=fgetc(*FILE);
3
>if(feof(*FILE))
4
>break;
5
>
6
>//....Verarbeitung....
7
>}
8
>
Könnte man.
Ist aber ziemlich umständlich. Wo man so ein Schema aber benutzen
kann ist, wenn das Lesen selbst aus mehreren einzelnen Leseoperationen
besteht.
> Dann bleibt die Geschichte aber hängen, wenn ein anderer Fehler> auftritt. Also macht:>
1
>while((InChar=fgetc(*FILE))!=EOF){
2
>// ....Verarbeitung....
3
>}
4
>//Test ob Abbruch wegen Dateiende
5
>if(!feof)
6
>printf("Datei konnte nicht richtig eingelesen werden...");
7
>
> wohl mehr Sinn. Zumindest wenn ich das richtig verstanden hab.
Du hast.
Das ist die Standardform, mit der man die Einleserei macht.
In diesem Fall: Die Klammerung in der Bedingung der while
Schleife nicht vergessen! Das gibt sonst überraschende Ergebnisse.
> Also war> mein Fehler, dass im Prinzip die letzte -1 auch noch geschrieben wurde,> oder?
Genau.
Meist findest du den Fehler in folgender Form:
while( !feof( in ) ) {
fgets( buffer, sizeof( buffer ), in );
printf( "%s" );
}
und die Frage, die dann auftaucht lautet: Warum wird die
letzte Zeile in meiner Datei doppelt ausgegeben (bearbeitet)?
Sollte jetzt klar sein, warum das so ist.
Dieser Fehler ist natürlich besonders peinlich, wenn in der
Datei zb. Abbuchungen von einem Konto stehen. Der (Bank-)Kunde
wird sich schön bedanken, wenn ihm eine Abbuchung doppelt vom
Konto abgezogen wirde, nur weil zufällig seine Transaktion die
letzte in der Datei war.
> Es ist übrigens wirklich so, dass ich bei mehreren Beispielen im Netz> den Test mit while(!feof()){...} gefunden hab.
Traurig, aber wahr. Dasselbe Problem findet sich auch in vielen
Büchern.
Die interessantere Frage lautet doch: Warum ist das so?
In anderen Sprachen ist das nämlich nicht so. Da wird eof
mit dem letzten gelesenen Zeichen gesetzt. Nicht so in C.
Der Grund liegt in der Vereinheitlichung aller Eingaben zum
Standard-Eingabe Mechanismus 'stream'. Egal ob eine Eingabe
von einem Keyboard kommt, von einem File, von einer Modemverbindung
etc. immer landet, aus C-Sicht, alles in einem Stream. D.h. aber
auch, man braucht vereinheitlichte Mechanismen. Wie willst du
aber feststellen, ob diese Eingabe vom Benutzer tatsächlich
jetzt die letzte wahr? Nur weil der Input Buffer zur Zeit leer
ist, heist das ja nicht, dass der Benutzer keine Eingaben mehr
machen will. Oder eine Modemstrecke? Nur weil zur Zeit kein
Zeichen auf der UART liegt, muss ja die Übertragung noch lange
nicht zu Ende sein. Während dein Programm dieses eine Zeichen
verarbeitet, könnte ja immer noch ein neues Zeichen auf der
UART eintrudeln. Dasselbe mit Files. Auf Unix Systemen ist es
durchaus möglich, dass 2 Programme ein und dieselbe Datei
gleichzeitig geöffnet haben. Während der eine liest, schreibt
das andere Programm munter in die Datei.
Also: Selbst wenn das letzte Zeichen vom Strom gelesen wurde,
heist das nicht notwendigerweise, dass damit eof() erreicht
ist. Während dieses letzte Zeichen bearbeitet wird, könnte
ein neues letztes Zeichen eintrudeln. Erst wenn beim
nächsten Leseversuch dann tatsächlich keines vorhanden ist,
kann man davon ausgehen, dass damit auch wirklich eof
erreicht ist. Das kann zb im Falle eines Modems auch bedeuten,
dass ein Timeout abgewartet werden muss oder im Falle eines
Terminals der Benutzer eof extra signalisieren muss (CTRL-Z oder
CTRL-D).
Aus Sicht des Programmes macht das aber alles keinen Unterschied.
Die Frage lautet ganz einfach: Konnte gelesen werden oder konnte
nicht.