problem with reding a text file into vector< vector<string> >
-
Hi, i have the problem mentioned in the header: my file looks as this:
Iso: pfmkk600ta70lp703
T050S 1
D05030 2Iso: pfmzv600ta70000
T050S 1
D05030 1
R0500200S 9
R0501000S 1and so on. All terms shall be stored into different containers:Iso.. into a vector,
T050S and so on into a vector< vector<string> > and the numbers like 9 into
vector< vector<int> >.my code is this:
#include <iostream> #include <fstream> #include <string> #include <vector> #include <sstream> #include <stdio.h> using namespace std; int main() { FILE *file; vector<string> isometrie; vector < vector<int> > isorohranzahl; vector < vector<string> > isorohrtypen; char tempchar[30]; vector<string> tempstring; int x; int w; file = fopen("isometrien.txt", "r"); if(file==NULL) { printf("Error: can't open file.\n"); return 1; } else { printf("File opened successfully.\n"); w = 0 ; x=0; while(!feof(file)) { isom:; fscanf(file, "%s", tempchar); //read line tempstring.insert(tempstring.end(),tempchar); //store c string into tempchar size_t findiso=tempstring[x].find_last_of("Iso"); // insert into stringvector tempstring if (findiso!=string::npos) //if string contains "iso", create new vector in isorohrtypen and isorohranzahl {isometrie.insert(isometrie.end(),tempchar); w++; x++; isorohrtypen.resize(w); isorohranzahl.resize(w); goto isom; } if(findiso=string::npos) {x++; isorohrtypen[w].insert(isorohrtypen[w].end(),tempchar); //if "iso" not found, string is a rohr, i.e. insert tempchar into rohrtypen isorohranzahl[w].resize(x); fscanf(file,"%d",&isorohranzahl[w][x]); }} // show result int g; int t; for (t=0; t<2; t++) {cout<<isometrie[t]<<endl; for (g=0; g<2 ;g++) { cout<<isorohrtypen[t][g]<<" "<<isorohranzahl[t][g]<<endl; } }} fclose(file); cin.get(); }i do not get any error messages from the compiler (dev-c++),
but a windows-window pops up and says "there is a problem" and the program doesnt work. could anyone help me, i guess there is a problem with the code
?best, sajakob
/edit by pumuckl: removed quote tags inside cpp tags (they are for quoting other people's posts, not code...)
-
Ich schreib mal auf deutsch weil ich deinen Variablennamen entnehme dass du deutsch kannst. Hier ein paar grundsätzliche Anmerkungen:
- Dev-Cpp ist veraltet. Siehe dazu auch den entsprechenden Thread in der Compiler-und IDE FAQ.
- Mische nicht C++ und C. <stdio.h> ist ein C-Header, in C++ heißt der <cstdio>, allerdings haben die C-Funktionalitäten die du daraus verwendet hast, Nachfolge in C++, so dass du den Header überhaupt nicht brauchst:
[list][]statt FILE benutze fstreams, du hast den passenden Header ja schon eingebaut. []statt printf benutze cout, auch da hast du den passenden Header schon drin.Wenn du das umsetzt, sieht dein Code schonmal sehr anders (und auch übersichtlicher) aus und man kann sich auf die Suche nach dem eigentlichen Problem machen.
PS: ich seh grade dass du sowohl printf als auch cout benutzt. Das lässt vermuten, dass du dir den Code einfach irgendwie zusammenkopiert hast. So lernt mans nicht.
-
ok vielen dank für die tipps
. ich habe jetzt versucht die dinge zu ändern, welche du bemängelt hast, und noch ein paar kleinigkeiten:#include <iostream> #include <fstream> #include <string> #include <vector> #include <sstream> using namespace std; int main() { vector<string> isometrie; vector < vector<int> > isorohranzahl; vector < vector<string> > isorohrtypen; vector<string> tempstring; int x; int w; char tempchar[20]; fstream file; file.open("isometrien.txt", ios::out); if(file.is_open()==false) { cout<<"Error: can't open file.\n"; return 1; } else { cout<<"File opened successfully."<<"\n"; w = 0 ; x=0; isom:; int p=0; while(!file.eof()) { file.getline(tempchar,20); tempstring.insert(tempstring.end(),tempchar); size_t findiso=tempstring[x].find_last_of("Iso"); if (findiso!=string::npos) {isometrie.insert(isometrie.end(),tempstring[x]); w++; x++; isorohrtypen.resize(w); isorohranzahl.resize(w); goto isom; } if(findiso=string::npos) {int n=0; p++; size_t find_=tempstring[x].find_last_of(" "); isorohranzahl[w].resize(p); stringstream(tempstring[x].substr(find_+1))>>isorohranzahl[w][p]; isorohrtypen[w].insert(isorohrtypen[w].end(),tempstring[x].substr(0, find_)); x++; }} int g; int t; for (t=0; t<w; t++) {cout<<isometrie[t]<<endl; for (g=0; g<(int) isorohranzahl[t].size();g++) { cout<<isorohrtypen[t][g]<<" "<<isorohranzahl[t][g]<<endl; } }} file.close(); cin.get(); }problem ist immernoch da: editor gibt "file opened successfully" und windowsfenster poppt hoch und gibt an, dass es ein fehler gegeben hat. Sind weitere grundlegende unstimmigkeiten zu sehen?
-
Kannst du vielleicht mal kurz erklären was dein Programm machen soll?
Das ist nämlich recht wüst ^^
Ich denke du willst irgendwie aus dem Textfile auslesen welche Rohre in welcher Stückzahl vorhanden sind. Da würde sich eigentlich ein wenig OOP anbieten.
eine Klasse Rohr, die ISO-Nummer speichert und Infos gibt über Länge, Durchmesser, Wanddicke, usw.
Eine Klasse RohrLager, die für jeden Rohrtyp eine Anzahl speichert.
oder in der Art.Denn getrennte Listen, die irgendwie dann über Indizes gemappt werden sind nicht recht schön...
(Ich bin aber jetzt nicht tiefer in deine Programmlogik eingestiegen, ist immerhin Sonntag ;))
-
genau: es gibt sogenannte isometrien (gewisse zusammenstellungen von rohren) diese sollen in einem vector gespeichert werden, und es gibt die dazugehörigen rohre mit ihrer anzahl welche jeweils in "matrizen" gespeichert werden sollten.
es muss im nachhinein auf all diese parameter zurückgegriffen werden können, und die anzahl der elemente in den containern sollte variabel bleiben, deshalb dachte ich vectoren seien das richtige.
vielen dank, ich schaue mal nach OOP...

-
sajakob schrieb:
... ich schaue mal nach OOP...

Ja, das ist eine gute Idee! Wenn man einen Datensatz als Klasse oder Struktur modelliert, tut man sich leichter. Das Einlesen eines Datensatzes ist ein bisschen tricky, da das Ende eines Datensatzes nur durch den Anfang des nächsten gebildet wird.
So geht's:
#include <iostream> #include <fstream> #include <string> #include <vector> #include <limits> // -- ein Datensatz als struct modelliert struct IsoWeisNichWas // bitte selber einen passenden Namen geben { friend std::istream& operator>>( std::istream& in, IsoWeisNichWas& x ); struct RohrEintrag { std::string m_typ; int m_anzahl; }; std::string m_isometrie; std::vector< RohrEintrag > m_rohrEintraege; }; std::istream& operator>>( std::istream& in, IsoWeisNichWas& x ) { using namespace std; if( in >> x.m_isometrie ) { vector< IsoWeisNichWas::RohrEintrag > rohrEintraege; // Bem.: hier wird ausgenutzt, dass das erste Wort eines Datensatzes 'Iso:' ist. // aus dem selben Grund muss das Fileende berücksicht werden, damit der Stream beim letzten Datensatz nicht in den Zustand fail rutscht. for( IsoWeisNichWas::RohrEintrag r; !in.eof() && !(in >> ws).eof() && in >> r.m_typ && r.m_typ != "Iso:" && in >> r.m_anzahl; ) rohrEintraege.push_back( r ); // alles ok, dann Rohreintrag speichern swap( rohrEintraege, x.m_rohrEintraege ); // eingelesen Rohrtypen übernehmen } return in; } int main() { using namespace std; vector< IsoWeisNichWas > ergebnis; ifstream file( "isometrien.txt" ); file.ignore( numeric_limits< streamsize >::max(), ':' ); // erstes "Iso:" überlesen for( IsoWeisNichWas x; file >> x; ) // bis Fehler oder End-Of-File ergebnis.push_back( x ); if( file.eof() ) { // alles iO.; Lesen ist bei End-Of-File angekommen cout << ergebnis.size() << " Datensaetze gelesen" << endl; // das Ergebnis steht jetzt in 'ergebnis' // ... } cin.get(); }Schau Dir auch dieses Posting an, das hilft beim Verstehen.
Gruß
Werner
-
besten dank werner
, ich brauche ein bisschen um zum verstehen, aber gut das spornt antrotzdem finde ich in meinem weniger eleganten versuch den fehler nicht. ABER wenn ich zeilen 50-52 (in dem als 2. aufgeführten code) ignoriere kommt keine fehlermeldung.