2016-09-22 1 views
0

Ich habe eine CSV-Datei mit Daten durch Kommata getrennt. Die Datei sieht wie folgt aus:Wie mit CSV-Datei Eingabestream, wo ich die Daten in jeder Zeile der Datei in 6 verschiedenen Varaibles (Typen Zeichenfolge und Int) teilen müssen

1998,MALE,United States,45,566 
1993,FEMALE,...... 

ich einen Vektor der Klasse Zeile und jede Zeile aus der Datendatei haben werde wird dort gespeichert. Mein ROW hat 5 Variablen und ich muss sie trennen, damit ich die Set-Funktion zu row.set(year,sex, country, score, result) verwenden kann.

Irgendeine Idee, wie man die Daten einliest?

Von dem, was mir gesagt wurde, sollte ich versuchen, getline zu vermeiden. Ich möchte nicht string s zu int s konvertieren.

Irgendwelche Ideen?

+0

Mit 'getline' und konvertieren' string's zu 'int's ist eigentlich trivialer Code zu schreiben und es ist oft viel sicherer, die Konvertierung selbst vorzunehmen, damit man schlechte Eingaben besser einfangen kann. Die Alternative besteht darin, dem Eingabestream beizubringen, Kommas als Leerzeichen zu behandeln. Gutes Beispiel hier: http://stackoverflow.com/questions/5607589/right-way-to-split-anstststring-into-a-vectorstring – user4581301

Antwort

1

Ich würde wahrscheinlich mit einem kleinen Operator beginnt die Anwesenheit von (aber ansonsten ignorieren) eine Zeichenfolge, so etwas zu überprüfen:

std::istream &operator>>(std::istream &is, char const *pat) { 

    char ch; 
    while (isspace(static_cast<unsigned char>(is.peek()))) 
     is.get(ch); 

    while (*pat && is && *pat == is.peek() && is.get(ch)) { 
     ++pat; 
    } 

    // if we didn't reach the end of the pattern, matching failed (mismatch, premature EOF, etc.) 
    if (*pat) { 
     is.setstate(std::ios::failbit); 
    } 

    return is; 
} 

Wir diese verwenden können, um das Vorhandensein von Kommas, um zu überprüfen, wo nötig, aber Ansonsten ignoriere sie ziemlich schmerzlos. Ich würde überlasten dann operator>> für den ROW Typ in geeigneter Weise die Daten zu lesen:

class ROW { 
    int year; 
    enum { MALE, FEMALE} sex; 
    std::string country; 
    int foo; 
    int bar; 

    friend std::istream &operator>>(std::istream &is, ROW &r) { 
     is >> r.year >> ","; 
     std::string s; 
     is >> s >> ","; 
     if (s == "MALE") 
      r.sex = MALE; 
     else if (s == "FEMALE") 
      r.sex = FEMALE; 
     else 
      error("bad sex"); 
     std::getline(is, r.country, ','); 
     return is >> r.foo >> "," >> r.bar; 
    } 
}; 

Von dort wir ziemlich direkt einen Vektor erstellen:

// Open the file 
std::ifstream in("data.txt"); 

// Read all the data 
std::vector<ROW> rows { std::istream_iterator<ROW>(in), {}}; 
+0

Ich mag den Operator nicht. Ein Manipulator wäre expressiver. –

Verwandte Themen