Über IStream einlesen und sortieren
-
Danke für deine Antwort KasF!
Getline zu benutzen kam mir auch schon in den Sinn. Doof dabei ist, dass ich nur ein Abbruchkriterium haben kann.
Das mit String kann ich mir vorstellen, hallte ich jedoch für sehr umständlich, die PersonenDaten sind alles char-Arrays. Das müsste ich dann wieder kopieren usw.Mein Prof. meinte gestern, ich müsste dass dann doch zeichweise einlesen und auswerten über cin.get o.Ä. - Mist!

-
DaDaUrka schrieb:
Das mit String kann ich mir vorstellen, hallte ich jedoch für sehr umständlich, die PersonenDaten sind alles char-Arrays. Das müsste ich dann wieder kopieren usw.
Das macht nichts. Am besten wäre es aber wenn du von Anfang an überall std::string hättest.
/* #include <fstream> #include <string> #include <sstream> #include <algorithm> #include <iterator> */ ifstream file("testo.txt"); string textFile = string(istreambuf_iterator<char>(file), istreambuf_iterator<char>()); replace(textFile.begin(),textFile.end(),',',' '); istringstream newFile(textFile); PersonenListenElement a; feed(newFile,&a);Frage an die Experten:
Wieso funktionier das nur so:string textFile = string(istreambuf_iterator<char>(file), istreambuf_iterator<char>());und nicht so:
string textFile(istreambuf_iterator<char>(file), istreambuf_iterator<char>());???
-
KasF schrieb:
Preisfrage an die Experten:
Wieso funktionier das nur so:string textFile = string(istreambuf_iterator<char>(file), istreambuf_iterator<char>());und nicht so:
string textFile(istreambuf_iterator<char>(file), istreambuf_iterator<char>());???
http://www.gotw.ca/gotw/075.htm - reicht das als Antwort?
-
CStoll schrieb:
Danke

( Kam vllt so rüber als ob ich das wüsste und euch testen wollte, aber dem war/ist nicht so :), habe mich nur gewundert wieso das nicht funktionierte )
-
Ich will jetzt nicht faul rüberkommen, aber der Testtreiber funzt wunderbar. Und will jetzt nicht alles auf string umschreiben. Zudem war es ja in der Aufgabenstellung gewollt, über iostreams ein-/auszulesen.
Ich werde mal am we das mal zeichenweise probieren.
-
DaDaUrka schrieb:
Zudem war es ja in der Aufgabenstellung gewollt, über iostreams ein-/auszulesen.
Was hat das eine mit dem anderen zu tun? char-Arrays sind Relikte aus C, in C++ kommst du mit std::string wesentlich schneller und einfacher zum Ziel als mit manuellen char*-Manipulationen.
-
Du musst auch nicht alles auf string umschreiben, eher gesagt gar nichts. Deine Struktur kann noch normal mit char* aufgaubt sein.
Aber machs lieber dann zeichenweise, damit sich dein Prof nicht wundert, woher du sowas zusammen gekratzt hast. Zeichenweise sollte auch nicht schwer sein. Einfach bei Problemen hier wieder fragen

-
Also ich habe jetzt folgendes probiert:
void PersonenListe::feed (istream & rein, PersonenListenElement * ple){ char buffer('\0'); int i(0); while(1){ rein.get(buffer); if(isalnum(buffer)) break; } ple->person.Nachname[0] = buffer; // Erstes Zeichen auf Nachname schieben i=1; // i auf 1 damit beim 2. Zeichen von Nachnae anschliesst while(1){ rein.get(buffer); // Nachname bis Whitespace oder , einlesen if(isalnum(buffer)){ ple->person.Nachname[i] = buffer; i++; }else break; } while(1){ rein.get(buffer); // Zum Vornamen springen if(isalnum(buffer))break; } ple->person.Vorname[0]=buffer; // Erstes Zeichen in Vornamen schieben i=1; // i auf 1 damit beim 2. Zeichen von Vorname anschliesst while(1){ rein.get(buffer); // Vorname bis Whiitespace oder , einlesen if(isalnum(buffer)){ ple->person.Vorname[i] = buffer; i++; }else break; } while(1){ rein.get(buffer); if(isalnum(buffer))break; } // Zum Geburstdatum springen ple->person.Geburtsdatum[0]=buffer; // Erstes Zeichen in Geburtsdatum schieben i=1; // i auf 1 damit beim 2. Zeichen von Geburtsdatum anschliesst while(1){ rein.get(buffer); // Geburtsdatum einlesen // Hier ist auch schon der Knackpunkt: // Der Istream schmeißt immer irgendeinen Mist noch hinten an das datum dran. Wieso? // Der DDD zeigt manchmal ein P bzw.A an ich glaube der will den Line Feed als char // noch akzeptieren und übersetzt ihn in ein Zeichen!? if(buffer>='0' && buffer <='9' || buffer == '.'){ ple->person.Geburtsdatum[i] = buffer; i++; }else break; } }Das funzt auch alles soweit, jedoch schmeißt mir das Programm hinten an den Geburtstag noch den Line Feed glaube dran und übersetzt das Zeichen.
Deswegen sieht die Ausgabe so aus:Bei einem Block:
----- Ausgabe ----- Max, Schmidt, 25.06.1986������,Bei mehr Blöcken:
----- Ausgabe ----- Max, Schmidt, 25.06.1986������A, Britta��������, Prause, 12.11.1987,Was könnte das sein?
-
Uiuiui, dein Code sieht nicht gerade sicher und auch sauber aus, aber egal wenn man so frickelt lernt man eh am besten

Das Problem kommt daher, dass du deine char*'s nicht mit einer 0 abschließst.
Beispiel beim ersten:
while(1){ rein.get(buffer); // Nachname bis Whitespace oder , einlesen if(isalnum(buffer)){ ple->person.Nachname[i] = buffer; i++; }else break; } ple->person.Nachname[i] = 0; // Zeichenkette abschließenBei den anderen dann auch ...
-
mhhh okay.
Ich nehme an manuell eine terminierende Null selbst rein machen wäre Stümper haft...

-
Topic mehr oder weniger gelöst:
Hab ganz vergessen noch meinen letzten Stand zu posten.
void PersonenListe::feed (istream & rein, PersonenListenElement * ple){ // Eine unelegante aber robuste Art(glaube ich zumindest) einzulesen // Fuer Vorschlaege bin ich sehr offen. :-) // Ueberschreibe alle Werte, weil er sonst Mist reinschreibt for(int j=0;j<=20;j++){ ple->person.Nachname[j]='\0'; } for(int j=0;j<=20;j++){ ple->person.Vorname[j]='\0'; } for(int j=0;j<=11;j++){ ple->person.Geburtsdatum[j]='\0'; } char buffer('\0'); int i(0); while(1){ rein.get(buffer); if(isalnum(buffer)) break; } ple->person.Nachname[0] = buffer; // Erstes Zeichen auf Nachname schieben i=1; // i auf 1 damit beim 2. Zeichen von Nachnae anschliesst while(1){ rein.get(buffer); // Nachname bis Whitespace oder , einlesen if(isalnum(buffer)){ if(i==20){break; cerr << endl << "Nachname zu lang." << endl;} ple->person.Nachname[i] = buffer; i++; }else break; } while(1){ rein.get(buffer); // Zum Vornamen springen if(isalnum(buffer))break; } ple->person.Vorname[0]=buffer; // Erstes Zeichen in Vornamen schieben i=1; // i auf 1 damit beim 2. Zeichen von Vorname anschliesst while(1){ rein.get(buffer); // Vorname bis Whiitespace oder , einlesen if(isalnum(buffer)){ if(i==20){break; cerr << endl << "Vorname zu lang." << endl;} ple->person.Vorname[i] = buffer; i++; }else break; } while(1){ rein.get(buffer); if(isalnum(buffer))break; } // Zum Geburstdatum springen ple->person.Geburtsdatum[0]=buffer; // Erstes Zeichen in Geburtsdatum schieben i=1; // i auf 1 damit beim 2. Zeichen von Geburtsdatum anschliesst // ple->person.Geburtsdatum[11]='\0'; // Der schreibt immer einen Mist hinten rein, vielleicht weil Person explizit nicht intialisiert ist!? while(1){ rein.get(buffer); // Geburtsdatum einlesen if(buffer>='0' && buffer <='9' || buffer == '.'){ if(i==11){break; cerr << endl << "Geburtsdatum zu lang." << endl;} ple->person.Geburtsdatum[i] = buffer; i++; }else break; } }Funzt soweit auch. Wie gesagt, sieht nicht grad toll aus, aber es klappt. In einem Jahr lache ich darüber, oder weine...
