Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Reading file Tokens

Tags:

c++

file

token

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?

like image 487
BobS Avatar asked Nov 08 '08 23:11

BobS


2 Answers

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";
    }
}
like image 128
Martin York Avatar answered Oct 02 '22 23:10

Martin York


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;
    }
}
like image 24
Johannes Schaub - litb Avatar answered Oct 02 '22 23:10

Johannes Schaub - litb