Datei einlesen klappt nicht wie beabsichtigt
-
Hallo zusammen, ich will eine simple Textdatei einlesen. Das Programm soll nur Zahlen einlesen, d.h. alle alphanumerischen Zeichen überspringen, und diese Zahlen dann in einem Vektor ablegen.
Inhalt von mydata.txt:
2 2 2Die Ausgabe meines Programms lautet:
End of file reached
2 2
Es vergisst aber die letzte 2, warum?Wenn ich den Inhalt von mydata.txt so abändere:
2 2 2f 5Dann gibt mein Programm das hier aus:
2 2 2
f wird übersprungen aber die 5 vergessen, scheinbar wird immer das letzte Zeichen vergessen.Wie muss mein Programm abgeändert werden damit es richtig arbeitet?
#include <iostream> #include <fstream> #include <vector> using namespace std; void fill_vector(istream& ist, vector<int>& v) { for(int n; ist>>n;) { if(ist.good()) v.push_back(n); if(ist.eof()) { cout << "End of file reached" << endl; return; } if(ist.fail()) { // we found something that wasn't an integer ist.clear(); // clear state to read character again for(char ch; ist>>ch && !isdigit(ch);) // throw away non-digits ; ist.unget(); // put the digit back, so that we can read the number } } } int main() { vector<int> v; ifstream ist {"mydata.txt"}; if(!ist.good()) cerr << "Cannot open File" << '\n'; fill_vector(ist, v); for(auto i : v) cout << i; }
-
@zipehpa sagte in Datei einlesen klappt nicht wie beabsichtigt:
for(int n; ist>>n;)
Was macht das? Wozu soll dann
if(ist.good())
if(ist.eof())
if(ist.fail())
gut sein?
-
Lass das selbstgemachte Prüfen weg! Wo hast du das überhaupt her? Der Leseoperator macht doch schon selber alles richtig:
for(int n; ist>>n;) v.push_back(n);
Das sollte schon reichen.
-
@zipehpa sagte in Datei einlesen klappt nicht wie beabsichtigt:
Das Programm soll nur Zahlen einlesen, d.h. alle alphanumerischen Zeichen überspringen
Das bedeutet für mich schon zwischen EOF und conversion failure unterscheiden.
bool valid_input; for (int n; (valid_input = !(ist >> n).fail()) || !ist.eof();) { // ach, das geht sicher eloganter if (valid_input) v.push_back(n); else { ist.clear(); ist.get(); } }
Ungetestet hingerotzt. TrotzdemKkeine Gewärleistung.
-
Hier mal mein Lösungsvorschlag:
#include <iostream> #include <string> #include <vector> #include <fstream> #include <sstream> void fill_vector(std::istream& ist, std::vector<int>& v) { std::stringstream ss; ss << ist.rdbuf(); for (const auto &ch : ss.str()) { if (ch >= '0' && ch <= '9') v.push_back(ch - '0'); } } int main() { std::vector<int> v; std::ifstream ist("test.txt"); if (!ist.good()) std::cerr << "Cannot open File" << '\n'; fill_vector(ist, v); for (const auto &number : v) { std::cout << number << '/'; } }
-
Man darf auch
'0'
und'9
' schreiben. Dann weiß jeder sofort, was gemeint ist; man kann nichts falsch machen; und es ist zumal noch viel portabler.
-
@SeppJ ja, vollkommen richtig. Habs geändert. Weiß auch nicht was mich geritten hat^^
-
@Zhavok
std::isdigit()
verdammt nochmal. Wenn schon.
-
OT, aber... weils in der Sig steht: Labskaus ist Rindfleisch und rote Beete.
-
@ks7776 Wie gesagt, der Koch ...