Datei elegant auslesen ?
-
Hi

Habe folgende Dateistruktur:
-- gfjkfkjg4t89 -- 4589gfkfjgfjg -- fgfgfg 445 34 78 876 54 34 -- fgfg 45Ich will nur die Zahlen habe, also die Zeilen die mit "--" anfangen sollen nicht beachtet werden!
while(!input.eof()) { input >> zahl; if(input.fail()) { char tempi[100]; input.clear(); input.ignore(); input.getline(tempi,100); } else { // mit zahl arbeiten } }Ist das so elegant oder gibt es besser Methoden ?
Der Grundgedanke war das ich immer in einen integer reinlese, folgedessen müsste ja ein Fehler entstehen wenn ich die "--" einlese.Also prüfe ich das mit fail() und lösche darauf die Fehlerflags, ignoriere den Müll im Stream und lese die Zeile bis zum Schluss ein damit ich in meiner nächsten Zeile bin...
Schön oder nicht Schön

-
Der Code ist auf jeden Fall richtig übel.
-
ich würde getline() verwenden, um die Datei zeilenweise einzulesen, jede Zeile mit substr() auf "--" vergleichen und bei Bedarf nach int umwandeln.
-
CStoll schrieb:
ich würde getline() verwenden, um die Datei zeilenweise einzulesen, jede Zeile mit substr() auf "--" vergleichen und bei Bedarf nach int umwandeln.
Ja klar so hab ich mir das am Anfang auch gedacht, es gibt ja mehere Methoden/Möglichkeiten um das auzulesen.
Die Zahlen tauchen ja öfters auf, als die anderen Zeilen und so hätte ich mir das umwandeln gespart, wenn ich direkt immer in einen int einlese...
Dennoch habe ich das Gefühl das das Programm was unsauber ist, weil ich ja den Fehler provozieren...
Ist den der Code trotzdem OK und wenn nicht, was genau ist nicht korrekt/gut ???
-
Hallo,
was hälst du von:string skip; int zahl; for (int peekChar = EOF; input && (peekChar = input.peek()) != EOF;) { if (peekChar == '-' ) getline(input, skip); else if (input >> zahl >> ws) { cout << zahl << endl; } }
-
da braucht man viel zu lange um den code zu raffen...
-
HumeSikkins schrieb:
Hallo,
was hälst du von:Wesentlich eleganter als meins

Damit habe ich mir auch die Umwandlung gespart...
-
Noch eleganter ist es eine Datei mit einer Struktur anzulegen.
Sie enthält beispielsweise einen Header, wo Informationen über Größe, Stringlänge ... enthalten sind.
-
Tc++H schrieb:
Noch eleganter ist es eine Datei mit einer Struktur anzulegen.
Sie enthält beispielsweise einen Header, wo Informationen über Größe, Stringlänge ... enthalten sind.
glaub ich nicht, Tim
-
Tc++H schrieb:
Noch eleganter ist es eine Datei mit einer Struktur anzulegen.
Sie enthält beispielsweise einen Header, wo Informationen über Größe, Stringlänge ... enthalten sind.
nein
-
@HumeSikkins: Mir ist da noch was eingefallen, was ich nicht so ganz verstehen...
HumeSikkins schrieb:
for (int peekChar = EOF; input && (peekChar = input.peek()) != EOF;) {Wieso wird da nochmal der stream überprüft.
Das ist doch das selbe als würde ich das so schreiben, oder ?for (int peekChar = EOF; !input.fail() && (peekChar = input.peek()) != EOF;) {Aber ist das schon auch schon hier gewährleistet das ich auf I/O Fehler überprüfe.
else if (input >> zahl >> ws)Da komme ich doch ne Refernz auf den Stream zurück,also ist das doch auch !input.fail()....
Oder ???
-
Freak_Coder schrieb:
HumeSikkins schrieb:
for (int peekChar = EOF; input && (peekChar = input.peek()) != EOF;) {Wieso wird da nochmal der stream überprüft.
[...]
Aber ist das schon auch schon hier gewährleistet das ich auf I/O Fehler überprüfe.
else if (input >> zahl >> ws)Da komme ich doch ne Refernz auf den Stream zurück,also ist das doch auch !input.fail()....
Oder ???
Die Streamprüfung in Der "Schleifenbedingung" ist trotzdem nötig, da zwar "if(cin >> zahl >> ws)" den stream prüft, das Konstrukt "getline(input, skip);" aber nicht...
Gruß Caipi
-
Hi Caipi,
aber wie kann den bei getline(input,skip) ein I/O - Fehler entstehen.
failbit wird doch nur gesetzt, wenn ich Daten in einen falschen Datentyp einlese.Wie kann denn bei getline ein Fehler entstehen, da wird doch egal was in der Datei steht in den string reinschrieben.

-
Freak_Coder schrieb:
Wie kann denn bei getline ein Fehler entstehen, da wird doch egal was in der Datei steht in den string reinschrieben.
Wenn nichts mehr drin steht gibts einen Fehler.
Kurt
-
ZuK schrieb:
Wenn nichts mehr drin steht gibts einen Fehler.
Genauer bitte ...
-
Beim Lesen trifft man auf eof und der Buffer ist auch leer. Dann z.B. (eof allein ist kein "Fehler")
Oder du liest vom USB-Stick und jemand rupft das Ding im Betrieb raus.
oder oder oder
Sei kreativ
-
Du sagst wenn du mit getline() eine Zeile einlesen willst dann kann's keinen Fehler geben. Ich sage wenn nichts in der Datei drin steht dann ist das ein Fehler ( eof ). Du willst über das Ende der Datei hinaus lesen.
Kurt
-
OK, jetzt nochmal langsam ....
for (int peekChar = EOF; input && (peekChar = input.peek()) != EOF;) { if (peekChar == '-' ) getline(input, skip); else if (input >> zahl >> ws) { cout << zahl << endl; } }Du/Ihr meint also das es sein könnte das ich mit getline EOF einlese... richtig ??
Aber das kann doch hier gar nicht passieren, denn getline kommt doch nur zum Einsatz wenn peekChar '-' ist.
Also wird folgedessen eine saubere Zeile eingelesen...
-----------------------------------------------------------------------------Es sei denn getline spielt dieses Spiel.
my.txtHallo§Das §-Zeichen steht hier für das Zeilenende, also EOF.
Wenn ich jetzt getline benutze, wird nur Hallo in den String geschrieben, oder Hallo plus das EOF ???Frage soviel weil ich die I/O-Streams von C++ richtig fest raffen will

Es kann auch sein das ich gerade ein Brett vorm Kopf habe und lieber aufhören sollte mich mit dem Englisch von Bruce Eckel herumzuschlagen
-
Zeilenende ('\n') ist etwas anderes als EOF
Wenn du getline() auf deine Datei anwendest, wird der String "HALLO" gelesen und der Lesezeiger landet auf dem Dateiende - wenn du jetzt nochmal getline() aufrufen würdest, erhältst du einen Fehler.
-
CStoll schrieb:
wenn du jetzt nochmal getline() aufrufen würdest, erhältst du einen Fehler.
Achso, aber dann kommt doch das ins Spiel:
(peekChar = input.peek()) != EOF;Ist denn somit nicht sichergestellt das getline nie ein EOF bekommt, denn es kommt ja nur zu Einsatz wenn peekChar '-' ist !
Also würde ich mit getline nie ein EOF einlesen, folgedessen sollte kein Fehler entstehen...
Immer noch nicht sicher bin wieso "input" in Bedingung stehen

-
Um es nochmal ganz deutlich zu machen: EOF ist kein Zeichen, sondern ein Zustand. Vielleicht hast du dich ja schon gefragt, warum peekChar ein int ist und kein char. Weil der Wert, der EOF repräsentiert nicht in char darstellbar ist, bzw. darstellbar sein darf.