Ifstream -> Ende der Datei in nächster Zeile?
-
Der Titel sagt wohl schon das meiste.
Ich will ein Programm schreiben, welches mir eine 2-spaltige txt-Datei einließt und den Mittelwert der 2. Spalte bildet.
Das Problem welches ich noch lösen will ist folgendes:
Ich verwende if-Stream und will mit eof() prüfen ob ich das Ende der Datei erreicht habe. Das Problem ist nun aber, dass der stream immer einen Wert zu viel ausließt. Er läuft also noch einen schleifendurchlauf zu viel durch und gibt mir den letzten Wert doppelt zurück (der ja in tmp gespeichert ist.)Hier mein Code:
float average(string filename, int row){ ifstream in(const_cast<char*>(filename.c_str()) ); int tmp; int N = 0; float sum = 0; float average = 0; while( !(in >> tmp) ) { in.clear(); in.ignore(numeric_limits<streamsize>::max(), '\n'); } in.unget(); for( int i = 0; !(in.eof()); i++ ){ for( int j = 1; j < 3; j++ ){ in >> tmp; if( j == row ){ cout << tmp << endl; sum+=tmp; N++; } } } average = sum/N; cout << "The sum is " << sum << endl; cout << "The average of the " << N << " datapoints is: " << average << endl; cout << "_________________" << endl; return average; }
-
ifstream in(const_cast<char*>(filename.c_str()) ); //Zeile 3
Wieso zum Teufel castest du?
(P.S.: Seit C++11 kann man auch direkt 'nenstring
übergeben)Wie ist die Datei aufgebaut?
So?0 8 2 9 684 654 5 1.4 6 .... 16 ...
-
Die Konstruktion
while( !EOF ) { in >> irgendwas; // mache was mit 'irgendwas'
.. ist derart verbreitet - ich habe sie auch schon in Lehrbüchern gesehen, dass sie viele unbedacht übernehmen.
Trotzdem ist sie fehlerhaft und führt u.a. zu dem von Tom_12345 beschriebenen Verhalten.Besser:
- Lese ein was auch immer Du willst
- prüfe danach(!), ob das gut gegangen istin diesem Fall in etwa so:
float average(string filename, int row) { ifstream in( filename.c_str() ); int tmp; while( !(in >> tmp) ) { in.clear(); in.ignore(numeric_limits<streamsize>::max(), '\n'); } in.unget(); // das Verfahren funktioniert nicht, wenn row==1 und tmp >9 ist int N = 0; float sum = 0; for( float tmp1, tmp2; in >> tmp1 >> tmp2; ++N ) { if( row == 1 ) sum += tmp1; else if( row == 2 ) sum += tmp2; } float average = sum/N; cout << "The sum is " << sum << endl; cout << "The average of the " << N << " datapoints is: " << average << endl; cout << "_________________" << endl; return average; }
-
Danke für die Antowrt Werner Solomon, damit hat sich mein Problem geklärt.
@Sone
Wenn ich nur den String filename übergebe, ohne den cast, bekomme ich für diese Zeile den Fehlerno matching function for call to ‘std::basic_ofstream<char>::basic_ofstream(std::string&)’
.
Was müsste ich denn verändern, damit ich dem Konstruktor mit ohne einen cast aufrufen kann? z.B.
ofstream out(file_out); wobei file_out ein String ist.
-
Tom_12345 schrieb:
ofstream out(file_out); wobei file_out ein String ist.
ofstream out(file_out.c_str());
oder den C++11-Standard benutzen.
-
SeppJ schrieb:
Tom_12345 schrieb:
ofstream out(file_out); wobei file_out ein String ist.
ofstream out(file_out.c_str());
oder den C++11-Standard benutzen.
Dasconst_cast
ist einfach total überflüssig.