2016-08-03 9 views
0

Ich habe Zeilen in einer Datei und jeder in der Zeile Fieled ist durch Leerzeichen getrennt. Hier ist ein simpliefied Beispiel einer Linie:Parsing einer Zeichenfolge mit Leerzeichen

208 "Person" "Anne Myers" "unsigned long" "hello" -1 false false false

Innerhalb eines Feldes werden einige Wörter durch Leerzeichen getrennt. d.h. "Anne Myers". Dies ist ein Problem beim Parsen.

Irgendwelche Vorschläge? Ausgabe sollte die 9 Felder für die weitere Verarbeitung sein. Ersetzen der Leerzeichen innerhalb des Feldes mit einem bestimmten Zeichen ist in meinem Fall nicht möglich.

Edit: Alle Zeilen folgen der gleichen Halbbildreihenfolge.

+0

Folgen alle Zeilen derselben Feldreihenfolge und demselben Typ? Wenn ja, können Sie reguläre Ausdrücke verwenden. – Sergey

+0

@Sergey gehen weg Regex – mash

+0

Was sollte in diesem Fall ausgegeben werden. – Shravan40

Antwort

0

Ein möglicher Ausgangspunkt wäre ein Typ sein, die operator>> Überlastungen korrekt Daten in diesem Format zu lesen:

class field { 
    std::string content; 
public: 
    friend std::istream &operator>>(std::istream &is, field &f) { 
     char ch; 

     // skip whitespace, then read one character 
     is >> ch; 

     // If it's a quote, read to the next quote 
     if (ch == '"') 
      std::getline(is, f.content, '"'); 
     else { 
      // otherwise put it back, and read until white-space: 
      is.unget(); 
      std::getline(is, f.content); 
     } 
     return is; 
    } 

    // While we're at it, I'm going to define output so we can see what was 
    // read in a single field easily: 
    friend std::ostream &operator<<(std::ostream &os, field const &f) { 
     return os << "[" << f.content << "]"; 
    } 
}; 

Dann können wir einen Datensatztyp für eine einzelne Zeile definieren, die diese Art für die entsprechenden Felder verwendet :

struct foo { 
    int a; 
    field b; 
    field c; 
    field d; 
    field e; 
    int f; 
    bool g, h, i; 

    friend std::istream &operator>>(std::istream &is, foo &f) { 
     return is >> std::boolalpha 
        >> f.a 
        >> f.b 
        >> f.c 
        >> f.d 
        >> f.e 
        >> f.f 
        >> f.g 
        >> f.h 
        >> f.i; 
    } 

    friend std::ostream &operator<<(std::ostream &os, foo &f) { 
     return os << std::boolalpha 
        << f.a << " " 
        << f.b 
        << f.c 
        << f.d 
        << f.e << " " 
        << f.f << " " 
        << f.g << " " 
        << f.h << " " 
        << f.i; 
    } 
}; 

Dann können wir Lese testen und schreiben einen Rekord:

int main() { 
    std::istringstream in 
     { R"(208 "Person" "Anne Myers" "unsigned long" "hello" -1 false false false)" }; 

    foo f; 

    in >> f; 
    std::cout << f; 
} 

Ergebnis:

208 [Person][Anne Myers][unsigned long][hello] -1 false false false 

Dies gilt nicht (derzeit) versucht, mit einem Feld zu beschäftigen, die auch ein Anführungszeichen enthält. Das wäre möglich, indem wir entweder eine C-ähnliche Konvention verwenden, bei der wir das Anführungszeichen mit einem umgekehrten Schrägstrich verlassen, oder eine CSV-ähnliche Konvention, bei der wir ein Anführungszeichen einfügen, indem wir zwei Anführungszeichen in die Eingabe einfügen.

Zum Beispiel:

"Bill said: ""Go away""!" 

... würde als ein Feld analysiert werden, mit dem Text:

Bill said: "Go away"! 

Entweder ist ziemlich einfach zu addieren, aber Sie haben nicht gesagt, die (Wenn du beides unterstützen willst, habe ich es vorerst ausgelassen.