string einlesen + zeileninhalt trennen
-
CStoll schrieb:
Und schon ist die main-Funktion dreimal so lang - und mußt sich neben ihrer eigentlichen Aufgabe (Daten einlesen und sortieren) auch noch darum kümmern, die eingelesenen Daten zu interpretieren.
Ja, weil ich ein try catch rum gemacht und leerzeilen eingefügt hab. eigentlich sind nur 2 schleifen dazu gekommen. Wenn du willst, kannst du zeile 5 bis 14 in eine readFileData Funtion packen.
Sogar als template, damit ihr den Typ ändern könnt. Obwohl ich sowas so gut wie nie mache war es ganz einfach, damit es auch mit double geht. Das mit dem lexicalCast gefällt mir zwar nicht, aber ich kenn jetzt auch keine vernünftige Funktion in C++ die ne Exception wirft, wenn der Text garkeine Zahl ist. Aber ist schon total unleserlich so ne while schleife mit Funktionsaufruf.
Der Datentyp ist eine Einheit aus Zahl und String, den auseinanderzunehmen macht keinen Sinn - und die Funktion split() ist beschränkt auf Eingabesequenzen "Zahl (beliebiger Typ dank Template) - Trennzeichen - Zeichenkette", ist zwar ein Schritt in die richtige Richtung, aber letztendlich will man irgendwelche Daten einlesen - und dazu gehst du nicht weit genug.
Hat mir keiner gesagt, dass die neue Aufgabe jetzt ist beliebige Strukturen einzulesen. Aber man kann die Aufgabe ja einfach erweitern, damit sie zur überdimensionierten Lösung passt.
-
blaurot schrieb:
...Hat mir keiner gesagt, dass die neue Aufgabe jetzt ist beliebige Strukturen einzulesen....
Steht da aber:
End0X schrieb:
...der zeileninhalt voneinander getrennt werden und in variablen abgelegt...
Es mag sein, dass End0X nicht explizit gesagt hat (bzw. ihm nicht aufgefallen), dass damit seine "Zeile" zu einem neuen Datentypen mutiert, aber das ändert nichts daran, dass er genau das verlangt hat.
Gruß,
Simon2.
-
End0X schrieb:
hi leute,
die sufu des Forums hat mir leider in meinem fall nicht helfen können.
mein programm soll mit while(getline(datei,zeile)) mehrere zeilen einlesen, ok?
dabei soll aber gleich der zeileninhalt voneinander getrennt werden und in variablen abgelegt
1.blablabla 12.blablabla 7.blablabla usw.
zahl + trennzeichen + text
ich will also die zahlen vor dem trennzeichen extra haben, damit ich die zeilen sortieren kann
Nicht nur nen Teil zitieren.
-
Implementationsdetails (wie hier "while()") haben in fachlichen Anforderungen nichts verloren oder können höchstens der Erläuterung dienen.
ICH jedenfalls habe das lediglich verstanden als "so könnte ich mir das vorstellen" und nicht als "dieses Statement muss auf jeden Fall drin sein".Gruß,
Simon2.
-
Hi,
finde es echt prima, dass hier so hilfsbereite leute sind. Eine kleine Kritik zu Werner Salomon: Man braucht ja nicht unbedingt eine Struktur zum einlesen... eine main() mit 3 Zeilen hät's auch getan
Aber trotzdem danke!
Ich habe gerade das Problem, dass ich eine ganze Zeile aufsplitten muss, und zwar nicht in 2 Teile, sondern in ca. 30 (verschiedene). Mit scanf() geht es kinderleicht, nur allokiert das keinen Speicher. Daher wollte ich ostream verwenden (nur das hat leider keine Formtastrings).
Scheinbar ist das Herzstück des Auslesens dieses hier:
Werner Salomon schrieb:
// -- Entry lesen std::istream& operator>>( std::istream& in, entry& e ) { return std::getline( in >> e.m_nummer >> trenner, e.m_restText ); }
Aber wie soll dies dann bei 30 Strings/Integern etc. aussehen? Muss ich immer noch getline() benutzen (30 mal?!), oder kann man hier allein auf komfortable >>-Operatoren zurückgreifen? Gibt es überhaupt eine sinnvoll Lösung für mein Problem?
Gruß,
Johannes
-
voidpointer schrieb:
Scheinbar ist das Herzstück des Auslesens dieses hier:
Werner Salomon schrieb:
// -- Entry lesen std::istream& operator>>( std::istream& in, entry& e ) { return std::getline( in >> e.m_nummer >> trenner, e.m_restText ); }
Aber wie soll dies dann bei 30 Strings/Integern etc. aussehen? Muss ich immer noch getline() benutzen (30 mal?!), oder kann man hier allein auf komfortable >>-Operatoren zurückgreifen? Gibt es überhaupt eine sinnvoll Lösung für mein Problem?
Hallo Johannes,
das getline, in dem Code-Stück oben, liest nur den letzen Rest der Zeile (m_restText). Aufgedröselt sähe es so aus:
// -- Entry lesen std::istream& operator>>( std::istream& in, entry& e ) { in >> e.m_nummer; in >> trenner; std::getline( in, e.m_restText ); return in; }
Wenn Du 30 verschieden Variablen einlesen willst, so geht das im Prinzip so - und ohne getline
in >> v1 >> v2 >> v3 >> ... >> v29 >> v30;
wobei v1 bis v30 Variablen von jedem Typ sein dürfen, für die ein Einlese-operator (>>) existiert.
Was sind denn das genau für Typen, welche Bedeutung haben sie und wie ist das Format Deiner Datei?Gruß
Werner
-
Hi,
Ich möchte die Datei
http://d3.descent.cx/d3cxraw.d3
auslesen. Wie man sieht, sind fast alles Integer und Strings, und das Trennzeichen ist fast immer '|' (Das Pipezeichen). Mit fscanf hatte ich dies immer so gemacht:fscanf(fp,"%f|%[^|]|%hd|%[^|]|%d|%[^|]|%[^|]|%hd|%hd|%[^|]|", ...)
u.s.w.
Kann ich mit den Operatoren von std::istream auch dieses Pipe-Trennzeichen festlegen und nutzen?
Gruß,
Johannes
-
voidpointer schrieb:
.. sondern in ca. 30 (verschiedene). Mit scanf() geht es kinderleicht, ..
voidpointer schrieb:
Mit fscanf hatte ich dies immer so gemacht:
fscanf(fp,"%f|%[^|]|%hd|%[^|]|%d|%[^|]|%[^|]|%hd|%hd|%[^|]|", ...)
u.s.w.
Hallo Johannes,
.. das ist also kinderleicht. Ich habe diese scanf-Syntax leider schon längst vergessen.
voidpointer schrieb:
Kann ich mit den Operatoren von std::istream auch dieses Pipe-Trennzeichen festlegen und nutzen?
ja das geht, wenn auch mit wesentlich 'mehr Code' als bei der scanf-Lösung. Im Prinzip so:
// f1 s1 i1 s2 i2 s3 istringstream in("1.0|Retail 1.4.0|11|[AUS] Server 2|2093|waltznmatilda.mn3|Anarchy|... "); double f1; int i1, i2; string s1, s2, s3; getline( in >> f1 >> trenner<'|'>, s1, '|' ); getline( in >> i1 >> trenner<'|'>, s2, '|' ); getline( in >> i2 >> trenner<'|'>, s3, '|' ); // usw.
Der Trenner ist wieder der gleiche wie schon in einigen Threads vorher.
template< char D > std::istream& trenner( std::istream& in ) { char t; if( in >> t && t != D ) in.setstate( std::ios_base::failbit ); return in; }
Gruß
Werner
-
Vielen Dank, funktioniert prima
Ist zwar leider etwas länger und evtl. unübersichtlicher als scanf()... aber was tut man nicht alles, um die string-Klasse zu benutzen
-
voidpointer schrieb:
...unübersichtlicher als scanf()...
Stimmt, meine 9jährigen Töchter haben das hier:
voidpointer schrieb:
..fscanf(fp,"%f|%[|]|%hd|%[|]|%d|%[|]|%[|]|%hd|%hd|%[^|]|"...
auf Anhieb verstanden ! :p
Gruß,
Simon2.