tags:

views:

3947

answers:

3

Hi, another request sorry.. Right now I am reading the tokens in one by one and it works, but I want to know when there is a new line..

if my file contains

Hey Bob
Now

should give me

Hey
Bob
[NEW LINE]
NOW

Is there a way to do this without using getline?

+7  A: 

Yes the operator>> when used with string read 'white space' separated words. A 'White space' includes space tab and new line characters.

If you want to read a line at a time use std::getline()
The line can then be tokenized separately with a string stream.

std::string   line;
while(std::getline(std::cin,line))
{

    // If you then want to tokenize the line use a string stream:

    std::stringstream lineStream(line);
    std::string token;
    while(lineStream >> token)
    {
        std::cout << "Token(" << token << ")\n";
    }

    std::cout << "New Line Detected\n";
}

Small addition:

Without using getline()

So you really want to be able to detect a newline. This means that newline becomes another type of token. So lets assume that you have words separated by 'white spaces' as tokens and newline as its own token.

Then you can create a Token type.
Then all you have to do is write the stream operators for a token:

#include <iostream>
#include <fstream>

class Token
{
    private:
        friend std::ostream& operator<<(std::ostream&,Token const&);
        friend std::istream& operator>>(std::istream&,Token&);
        std::string     value;
};
std::istream& operator>>(std::istream& str,Token& data)
{
    // Check to make sure the stream is OK.
    if (!str)
    {   return str;
    }

    char    x;
    // Drop leading space
    do
    {
        x = str.get();
    }
    while(str && isspace(x) && (x != '\n'));

    // If the stream is done. exit now.
    if (!str)
    {
        return str;
    }

    // We have skipped all white space up to the
    // start of the first token. We can now modify data.
    data.value  ="";

    // If the token is a '\n' We are finished.
    if (x == '\n')
    {   data.value  = "\n";
        return str;
    }

    // Otherwise read the next token in.
    str.unget();
    str >> data.value;

    return str;
}
std::ostream& operator<<(std::ostream& str,Token const& data)
{
    return str << data.value;
}


int main()
{
    std::ifstream   f("PLOP");
    Token   x;

    while(f >> x)
    {
        std::cout << "Token(" << x << ")\n";
    }
}
Martin York
A: 

I don't know why you think std::getline is bad. You can still recognize newlines.

std::string token;
std::ifstream file("file.txt");
while(std::getline(file, token)) {
    std::istringstream line(token);
    while(line >> token) {
        std::cout << "Token :" << token << std::endl;
    }
    if(file.unget().get() == '\n') {
        std::cout << "newline found" << std::endl;
    }
}
Johannes Schaub - litb
A: 

This is another cool and much less verbose way I came across to tokenize strings.

vector<string> vec; //we'll put all of the tokens in here 
string token;
istringstream iss("put text here"); 

while ( getline(iss, token, '\n') ) {
       vec.push_back(token);
}
the_drow