2012-10-15 6 views
5

Was ist der sauberste Weg, um den Effekt von istream::getline(string, 256, '\n' OR ';') zu bekommen?So etwas wie istream :: getline() aber mit alternativen delim Zeichen?

Ich weiß, es ist ziemlich einfach, eine Schleife zu schreiben, aber ich fühle, dass ich etwas verpassen könnte. Bin ich?

Was ich verwendet:

while ((is.peek() != '\n') && (is.peek() != ';')) 
    stringstream.put(is.get()); 

Antwort

3

Leider gibt es keine Möglichkeit, mehrere "Zeilenenden" zu haben. Was Sie tun können, ist die Zeile mit z.B. std::getline und setzen Sie es in eine std::istringstream und verwenden Sie std::getline (mit dem ';' Separator) in einer Schleife auf dem istringstream.

Obwohl Sie die Boost iostreams Bibliothek überprüfen können, um es zu sehen, hat es Funktionalität dafür.

+0

Ok, danke, das ist ganz nett! Ich schrieb eine Schleife, die std :: stringstream.put(): ed jedes char, bis es gefunden '\ n' oder ';', und dann stringstream.str() verwendet, um die Zeichenfolge zu erhalten. – Erika

3

dort ist std::getline. Für komplexere Szenarien könnte man versuchen, istream_iterator oder istreambuf_iterator mit boost split oder regex_iterator (here is an example der Verwendung von Stream-Iteratoren) zu splitten.

+2

'std :: getline' ist gut, weil es eine Überlastung für' std hat: : string', was die String-I/O viel, viel einfacher macht (zumindest meiner Meinung nach). – dreamlax

+2

'std :: getline' hilft in diesem Fall nicht, wenn das OP mehrere Zeilenenden/Trennzeichen haben möchte. –

0

Hier ist eine funktionierende Implementierung:

enum class cascade { yes, no }; 
std::istream& getline(std::istream& stream, std::string& line, const std::string& delim, cascade c = cascade::yes){ 
    line.clear(); 
    std::string::value_type ch; 
    bool stream_altered = false; 
    while(stream.get(ch) && (stream_altered = true)){ 
     if(delim.find(ch) == std::string::npos) 
      line += ch; 
     else if(c == cascade::yes && line.empty()) 
      continue; 
     else break; 
    } 
    if(stream.eof() && stream_altered) stream.clear(std::ios_base::eofbit); 
    return stream; 
} 

Die cascade::yes Option kollabiert Aufeinander folgende Trennzeichen gefunden. Mit cascade::no wird für jeden zweiten gefundenen Delimeter eine leere Zeichenfolge zurückgegeben.

Verbrauch:

const std::string punctuation = ",.';:?"; 
std::string words; 
while(getline(istream_object, words, punctuation)) 
    std::cout << word << std::endl; 

seine Verwendung Siehe Live on Coliru

Eine generische Ausführung wird this