C++ unter Linux aus Tabelle einlesen
-
Ich kann ja mal die ersten Zeilen der Tabelle hier zeigen:
ARC_ID_DVSN;ARC_ID_CITY;SHARE_DVSN;ARC_ID_Ret_Flow
40121;43973;1;43973
40121;43974;1;43974
40121;43975;1;43975
40121;43976;1;43976
429438;44005;0,25;44005
45235;44005;0,25;44005
45236;44005;0,25;44005
45533;44005;0,25;44005
429438;44006;0,25;44006
45235;44006;0,25;44006
45236;44006;0,25;44006
45533;44006;0,25;44006
429438;44007;0,25;44007
45235;44007;0,25;44007
45236;44007;0,25;44007
45533;44007;0,25;44007
-
Vermutlich fehlt folgender Compiler-Switch: -std=c++11
-
Skym0sh0 schrieb:
Als Compileroption noch std=c++0x angeben.
Ich denke mal das du unter Windows programmierst oder? Wenn nicht kannst du mir da
weiter helfen also wie gesagt ich Programmier mit eclipse CDT unter Ubuntu.
-
Ok ich habs gefunden wie ich es in Eclipse einstelle. Code läuft fehlerfrei durch.
Danke.
Ich hab nur noch das Problem das er hier wohl die File gar nicht findet oder ich noch einen fehler habe.
std::ifstream file("./change_eu_utf.txt"); auto table = readTable(file);
-
So das funktioniert auch.
#include <iostream> #include <fstream> #include <vector> #include <string> std::vector<std::vector<std::string> > readTable(std::istream & is) { std::vector<std::vector<std::string> > table; while ( is ) { std::vector<std::string> line; for(std::size_t i = 0; i < 4; ++i) { std::string col; if ( std::getline(is, col, ';') ) { line.push_back(col); } } table.push_back(line); } return table; } int main() { std::ifstream file("./change_eu_utf.txt"); auto table = readTable(file); std::cout<<table.size(); // for(auto const& line : table) // { // std::cout<<std::endl<<"Zeile: "<<i++<<" "; // for(auto const& element : line) // { // // std::cout << element << '\t'; // } // //std::cout << std::endl; // } return 0x0; }Aber wenn ich mir jetzt die größe der tabell ausgeben lasse habe ich nur 6080 einträge aber es sollten 8105 sein.oder sehe ich das falsch?
-
Hallo Onubub,
Willkommen im C++-Forum!
Onubub schrieb:
So das funktioniert auch. ....
Nö - so funktioniert das nicht, da ich mir nicht vorstellen kann, dass Du direkt mit den Strings, die Ziffern enthalten weiter arbeiten kannst bzw. möchtest.
Wenn Du ints möchtest, so lese ints!
Und wenn ich das richtig sehe, so kann die dritte Spalte auch Fließkommazahlen enthalten und für diese wird das Komma als Dezimaltrenner benutzt (deutsche Schreibweise). Das gilt es alles zu beachten.
SeppJ hat schon erwähnt, dass es sinnvoll ist, die Werte einer Zeile zu einer Struktur zusammen zu fassen. Da sie allen Anschein nach auch noch von unterschiedlichen Typ sind, bietet sich einestructan.Anbei eine Skizze, die die von Dir gepostete Tabelle aus einer Datei einliest:
#include <iostream> #include <fstream> #include <vector> #include <limits> // numeric_limits struct EineStruct // eine struct, da ich nicht weiß was es ist halt 'EineStruct' { int id_dvsn; int id_city; double share_dvsn; // 3.Spalte ist eine Fließkommazahl int id_ret_flow; }; template< char C > // Helferlein zum Überlesen eines Zeichens 'C'; z.B.: ';' std::istream& Char( std::istream& in ) { char c; if( in >> c && c != C ) in.setstate( std::ios_base::failbit ); return in; } int main() { using namespace std; vector< EineStruct > table; // da kommt später die Tabelle rein, jede Zeile entspricht einem Element { // -- Tabelle lesen ifstream file("./change_eu_utf.txt"); if( !file.is_open() ) { cerr << "Fehler beim Oeffnen der Datei" << endl; return -2; } file.imbue( locale( "german" ) ); // auf ',' als Dezimaltrenner umschalten; ACHTUNG: 'german' kann in anderen IDEs anders heißen file.ignore( numeric_limits< streamsize >::max(), '\n' ); // erste Zeile überspringen for( EineStruct s; file >> s.id_dvsn >> Char<';'> >> s.id_city >> Char<';'> >> s.share_dvsn >> Char<';'> >> s.id_ret_flow; ) table.push_back( s ); if( !file.eof() ) // falls bis End-Of-File gelesen wurde, ist alles iO { cerr << "Fehler beim Lesen der Datei" << endl; return -1; } } cout << table.size() << " Eintraege gelesen" << endl; // usw. return 0; }Gruß
Werner
-
Werner Salomon schrieb:
Hallo Onubub,
Willkommen im C++-Forum!
Onubub schrieb:
So das funktioniert auch. ....
Nö - so funktioniert das nicht, da ich mir nicht vorstellen kann, dass Du direkt mit den Strings, die Ziffern enthalten weiter arbeiten kannst bzw. möchtest.
Wenn Du ints möchtest, so lese ints!
Und wenn ich das richtig sehe, so kann die dritte Spalte auch Fließkommazahlen enthalten und für diese wird das Komma als Dezimaltrenner benutzt (deutsche Schreibweise). Das gilt es alles zu beachten.
SeppJ hat schon erwähnt, dass es sinnvoll ist, die Werte einer Zeile zu einer Struktur zusammen zu fassen. Da sie allen Anschein nach auch noch von unterschiedlichen Typ sind, bietet sich einestructan.Anbei eine Skizze, die die von Dir gepostete Tabelle aus einer Datei einliest:
#include <iostream> #include <fstream> #include <vector> #include <limits> // numeric_limits struct EineStruct // eine struct, da ich nicht weiß was es ist halt 'EineStruct' { int id_dvsn; int id_city; double share_dvsn; // 3.Spalte ist eine Fließkommazahl int id_ret_flow; }; template< char C > // Helferlein zum Überlesen eines Zeichens 'C'; z.B.: ';' std::istream& Char( std::istream& in ) { char c; if( in >> c && c != C ) in.setstate( std::ios_base::failbit ); return in; } int main() { using namespace std; vector< EineStruct > table; // da kommt später die Tabelle rein, jede Zeile entspricht einem Element { // -- Tabelle lesen ifstream file("./change_eu_utf.txt"); if( !file.is_open() ) { cerr << "Fehler beim Oeffnen der Datei" << endl; return -2; } file.imbue( locale( "german" ) ); // auf ',' als Dezimaltrenner umschalten; ACHTUNG: 'german' kann in anderen IDEs anders heißen file.ignore( numeric_limits< streamsize >::max(), '\n' ); // erste Zeile überspringen for( EineStruct s; file >> s.id_dvsn >> Char<';'> >> s.id_city >> Char<';'> >> s.share_dvsn >> Char<';'> >> s.id_ret_flow; ) table.push_back( s ); if( !file.eof() ) // falls bis End-Of-File gelesen wurde, ist alles iO { cerr << "Fehler beim Lesen der Datei" << endl; return -1; } } cout << table.size() << " Eintraege gelesen" << endl; // usw. return 0; }Gruß
WernerDanke für die Hilfe.
Ja hast recht so wird es mich wohl weiter bringen, doch bekomm ich immer den fehler.terminate called after throwing an instance of 'std::runtime_error' what(): locale::facet::_S_create_c_locale name not validLiegt das an "german"? Ich kann die Tabellen aber auch so modifizieren das die Dezimalstellen mit '.' dargestellt werden.
-
Onubub schrieb:
Ja hast recht so wird es mich wohl weiter bringen, doch bekomm ich immer den fehler.
terminate called after throwing an instance of 'std::runtime_error' what(): locale::facet::_S_create_c_locale name not validLiegt das an "german"? Ich kann die Tabellen aber auch so modifizieren das die Dezimalstellen mit '.' dargestellt werden.
Ja - steht ja da: "locale name not valid"
Versuche mal "deu" (das ist nach ISO 639-2/3) - ansonsten verrate uns Deine Entwicklungsumgebung und dann weiß hier bestimmt jemand, was da einzustellen ist.Wenn Du die Datei auf '.' umstellen kannst, so geht das natürlich auch. Lasse in diesem Fall die Zeile 33 einfach weg.
Gruß
Werner
-
PS.:
.. unter Linux-Systemen soll man die locale-Namen mit
locale -aherausfinden können.
evt. geht auch "de_DE" oder "de_DE.UTF-8"
-
Ja klappt! Vielen Dank.