W
Hallo depream,
depream schrieb:
Meine Frage wäre mal vorne weg, ist es einfacher bzw. besser einen char zu splitten oder einen string?
am besten weder noch!
Was vielen Leuten nicht bewusst ist; es gibt in C++ einen std::istream in Form z.B. von cin oder ifstream. Und die Aufgabe dieses Streams ist es NICHT(nur) Zeichen aus einer Datei in den Speicher zu schaufeln - das könnte ein std::streambuf auch ganz allein, sondern aus einer Folge von Zeichen ein Objekt zu machen. Ein Objekt kann ein Zeichen, ein Integer, ein Datum oder eine TravelAgency sein. Die Folge von Zeichen kann in einer Datei oder im Memory (als String) stehen. Es bleibt eine Folge von Zeichen und das Lesen einer kompletten Zeile aus der Datei in einen String verschiebt das Problem nur und löst praktisch nichts (ok - nicht viel, aber dazu vielleicht später).
Th69 hat das schon vorgemacht. Wobei ich noch einen Schritte weiter gehe und nicht nur Strings lesen, sondern gleich die Objekte.
Um z.B. ein Zeichen oder ein Integer zu lesen gibt es Funktionen in C++.
ifstream datei(...);
char c; // ein Zeichen
datei >> c; // liest das Zeichen
if( datei )
{ // alles ok; usw.
In 'c' kann jetzt ein 'F' ein 'R' oder ein 'H' oder was anderes stehen.
Für das lesen (und prüfen) des Trennzeichens hält C++ auch etwas bereit. Zunächst wie oben:
char pipe_zeichen;
datei >> pipe_zeichen;
if( datei && pipe_zeichen == '|' )
{ // erst jetzt ist alles i.O.
Ein std::istream kann auch eine Funktion 'aufnehmen', die eine gewisse Manipulation vornimmt. Man nennt diese Funktion daher auch Manipulator. Sie muss folgende Signatur haben:
std::istream& 'name'( std::istream& );
'name' ist irgendein Name natürlich ohne ''. Angenommen es gibt einen Manipulator pipe - also:
std::istream& pipe( std::istream& );
dann kann man folgendes aufrufen:
datei >> pipe;
Hier wird diese Funktion dann mit 'datei' als Parameter aufgerufen und die Implementierung von pipe muss eine Referenz auf 'datei' wieder zurückgeben.
std::istream& pipe( std::istream& ) {
char pipe_zeichen;
in >> pipe_zeichen;
if( in && pipe_zeichen == '|' )
return in; // alles gut
in.setstate( std::ios_base::failbit ); // setzt das Fehlerbit im istream
return in;
}
eine fortgeschrittene Variante und weitere Tipps findest Du als Char<> hier.
Um die ersten beiden Objekte (Zeichen und Nummer) zu lesen reicht dann:
char c;
int nr;
datei >> c >> pipe >> nr;
if( datei )
{ // Erfolg
depream schrieb:
Falls möglich nicht explizit die Lösung verraten sondern ich würde es gerne selber versuchen, damit es auch hängen bleibt
dann versuche es mal selber weiter.
Noch eine Frage: In der 3. Zeile der Textdatei ist ein '|' weniger als in den anderen 4 Zeilen. Ist das ein Fehler oder können hinter dem zweiten Datum 'beliebig' viele Felder und damit '|'-Zeichen pro Datensatz kommen?
Gruß
Werner