5

What's the cleanest way of getting the effect of istream::getline(string, 256, '\n' OR ';')?

I know it's quite straightforward to write a loop, but I feel that I might be missing something. Am I?

What I used:

while ((is.peek() != '\n') && (is.peek() != ';'))
    stringstream.put(is.get());
einpoklum
  • 118,144
  • 57
  • 340
  • 684
Erika
  • 416
  • 5
  • 14

3 Answers3

3

There's std::getline. For more complex scenarios one might try splitting istream_iterator or istreambuf_iterator with boost split or regex_iterator (here is an example of using stream iterators).

Community
  • 1
  • 1
ArtemGr
  • 11,684
  • 3
  • 52
  • 85
3

Unfortunately there is no way to have multiple "line endings". What you can do is read the line with e.g. std::getline and put it in an std::istringstream and use std::getline (with the ';' separator) in a loop on the istringstream.

Although you could check the Boost iostreams library to see it it has functionality for it.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Ok, thanks, that's quite nice! I wrote a loop that std::stringstream.put():ed every char until it found '\n' or ';', and then used stringstream.str() to get the string. – Erika Oct 15 '12 at 08:02
0

Here is a working implementation:

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;
}

The cascade::yes option collapses consecutive delimiters found. With cascade::no, it will return an empty string for each a second consecutive delimeter found.

Usage:

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

See its usage Live on Coliru

A more generic version will be this

WhiZTiM
  • 21,207
  • 4
  • 43
  • 68