CSV Datei einlesen
-
Guten Morgen,
CSV Dateien sind ja wie TXT dateien, nur dass sie Datensätze zeilenweise abspeichern und diese mit ; voneinander trennen.Ich würde gerne das Datum (singular?) auslesen welches vor dem 8ten ; jeder Zeile kommt. Wie registriere ich, dass es sich um ein ; handelt?
Speicher ich dann alles in char?
Kann ich dann im Zeilendurchlauf nach auffinden des 8ten Zeichens wieder die Zeichen davor betrachten oder ist ein Zeilendurchlauf nur in die rechte Richtung möglich?Danke im Voraus
-
Kann ich dann im Zeilendurchlauf nach auffinden des 8ten Zeichens wieder die Zeichen davor betrachten oder ist ein Zeilendurchlauf nur in die rechte Richtung möglich?
Natürlich. Dafür nimmt man
std::istream::seekg.
Es ist aber recht umständlich. Am Besten liest du die Datei von Links nach Rechts aus.Wie registriere ich, dass es sich um ein ; handelt?
Indem du das mit dem gelesenen Zeichen vergleichst

Eigentlich macht das aber
std::basic_istream::ignorefür dich, mit dem du alle Zeichen bis zum nächsten Delimitter überspringst (wobei der Delimitter in deinem Fall';'wäre).Speicher ich dann alles in char?
Wie wäre es mit
std::tm?
-
nehme dieses Helferlein:
#include <istream> #include <limits> // numeric_limits struct skip_delimiter { skip_delimiter( char c, int anz ) : zeichen_( c ) , anz_( anz ) {} char zeichen_; int anz_; }; std::istream& operator>>( std::istream& in, skip_delimiter skippy ) { for( ; skippy.anz_ > 0; --skippy.anz_ ) in.ignore( std::numeric_limits< std::streamsize >::max(), skippy.zeichen_ ); return in; }und wende ihn so an:
ifstream file("datei.csv"); int datum; if( file >> skip_delimiter(';',7) >> datum ) // vor dem 8'ten ist nach dem 7'ten ';' cout << datum << endl;oder siehe hier: http://www.c-plusplus.net/forum/p2292030#2292030
Kromann schrieb:
Speicher ich dann alles in char?
besser nicht! Lese gleich das aus der Datei, was Du auch programm-intern benötigst.
Kromann schrieb:
Kann ich dann im Zeilendurchlauf nach auffinden des 8ten Zeichens wieder die Zeichen davor betrachten oder ist ein Zeilendurchlauf nur in die rechte Richtung möglich?
möglich, aber nicht zu empfehlen. Besser Du liest es gleich vorher ein. Was genau willst Du lesen und wie ist das Format der CSV-Datei?
Kromann schrieb:
Danke im Voraus
besser nachher Feedback geben

Nachtrag: das Helferlein
skip_delimiterzählt auch Trennzeichen';', die ggf.. in Hochkomma eingeschlossen sind!
-
Arcoth schrieb:
Kromann schrieb:
Speicher ich dann alles in char?
Wie wäre es mit
std::tm?Ich glaube hier hat Dich die Einzahl des Worts Daten auf den Holzweg geschickt...

-
Datum schrieb:
Arcoth schrieb:
Kromann schrieb:
Speicher ich dann alles in char?
Wie wäre es mit
std::tm?Ich glaube hier hat Dich die Einzahl des Worts Daten auf den Holzweg geschickt...

Jetzt verstehe ich das (singular?) im Text. (Dachte das bezog sich auf die Weise in der Eingelesen wird) Also ein
vectorvontms?@Werner: Bitte korrigiere dein Helferlein. Das ist naemlich inkorrekt.
Ich mache mal einen Vorschlag:
struct skip_delimiter { skip_delimiter( char c, std::streamsize anz ) : zeichen_( c ) , anz_( anz ) {} char zeichen_; std::streamsize anz_; // Hier lag der Fehler // Extra Helfer-Funktionen std::istream& ignore_one( std::istream& is ) const { return is.ignore( std::numeric_limits<std::streamsize>::max(), zeichen_ ); } std::istream& ignore_all( std::istream& is ) const { std::streamsize s = anz_; while( s-- ) ignore_one( is ); return is; } };(ungetestet)
-
Dann besser gleich einen Parser verwenden, der korrekt auch mit dem Feldbegrenzerzeichen (und weiteren Features) umgehen kann, z.B.
csv-parser-cplusplus
fast-cpp-csv-parser
-
Th69 schrieb:
Ieh!
csv_parser file_parser; /* Define how many records we're gonna skip. This could be used to skip the column definitions. */ file_parser.set_skip_lines(1); /* Specify the file to parse */ file_parser.init(filename);Initialisierung über Funktionen und nicht Konstruktor? Und
printfim Beispiel. Deutet auf nichts gutes hin.