Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ how to read a line with delimiter until the end of each line? [duplicate]

Tags:

c++

getline

Hi I need to read a file that looks like this...

1|Toy Story (1995)|Animation|Children's|Comedy
2|Jumanji (1995)|Adventure|Children's|Fantasy
3|Grumpier Old Men (1995)|Comedy|Romance
4|Waiting to Exhale (1995)|Comedy|Drama
5|Father of the Bride Part II (1995)|Comedy
6|Heat (1995)|Action|Crime|Thriller
7|Sabrina (1995)|Comedy|Romance
8|Tom and Huck (1995)|Adventure|Children's
9|Sudden Death (1995)|Action

As you can see the type of each movie can vary from 1 type to many...I wonder how could I read those until the end of each line?

I'm currently doing:

void readingenre(string filename,int **g)
{

    ifstream myfile(filename);
    cout << "reading file "+filename << endl;
    if(myfile.is_open())
    {
        string item;
        string name;
        string type;
        while(!myfile.eof())
        {
            getline(myfile,item,'|');
            //cout <<item<< "\t";
            getline(myfile,name,'|');
            while(getline(myfile,type,'|'))
            {
                cout<<type<<endl;
            }
            getline(myfile,type,'\n');
        }
        myfile.close();
        cout << "reading genre file finished" <<endl;
    }
}

the result is not what I want...It looks like:

Animation
Children's
Comedy
2
Jumanji (1995)
Adventure
Children's
Fantasy
3
Grumpier Old Men (1995)
Comedy
Romance

So it doesn't stop at the end of each line...How could I fix this?

like image 655
weeo Avatar asked Oct 28 '16 10:10

weeo


People also ask

How do I use Getline with delimiter?

Using std::getline() in C++ to split the input using delimiters. We can also use the delim argument to make the getline function split the input in terms of a delimiter character. By default, the delimiter is \n (newline). We can change this to make getline() split the input based on other characters too!

Can Getline have multiple delimiters?

No, std::getline () only accepts a single character, to override the default delimiter. std::getline() does not have an option for multiple alternate delimiters.

What does Getline return at end of file?

GetLine strips the carriage return and line feed characters from the end of the line it returns. When GetLine has read all the lines in a file, it returns an end-of-file error. If you open a file in append mode, the GetLine function fails if you call it because the file pointer is at the end of the file.

Does Getline go to the next line?

So getline never reads a second line because getline is never called a second time - the code gets stuck in the infinite loop before that can happen.


1 Answers

Attempting to parse this input file one field at a time is the wrong approach.

This is a text file. A text file consists of lines terminated by newline characters. getline() by itself, is what you use to read a text file, with newline-terminated lines:

while (std::getline(myfile, line))

And not:

while(!myfile.eof())

which is always a bug.

So now you have a loop that reads each line of text. A std::istringstream can be constructed inside the loop, containing the line just read:

   std::istringstream iline(line);

and then you can use std::getline(), with this std::istringstream with the optional delimiter character overriden to '|' to read each field in the line.

like image 163
Sam Varshavchik Avatar answered Sep 22 '22 12:09

Sam Varshavchik