Eduardo
Eduardo

Reputation: 7141

reading text with whitespaces in c++

i'm trying to read in the following text file into different variables:

title
subject name
123
subject2 name
124
subject3 name
125

so far i've been using the following code

ifstream myfile;
myfile.open("filename.txt");
......etc

myfile >> string1
while(myfile >> string2 && myfile >> int1){
    cout << "read string " << string2 << "and int " << int1 << endl;
}

This method doesn't seem to like the space between "subject name" and it isn't picking up so it doesn't run the while loop. Is there an easy way i can fix this?

Upvotes: 0

Views: 3432

Answers (2)

Petar
Petar

Reputation: 56

First problem I noticed when I looked at your code was the missing semicolon ; after

myfile >> string1 but this is just a syntax error.

The while loop you're trying to use will only evaluate when both conditions are true because you're using && operator.

As @sftrabbit said extraction operator >> in C++ leaves a new line character \n in the input buffer and then when you're trying to input

std::getline(myfile, string2) && myfile >> int1

First condition std::getline(myfile, string2) doesn't have a problem getting a new line character and will evaluate to true, but then second condition myfile >> int1 will evaluate to false because it will get a character(s) when it's expecting an integer. That's why your while loop doesn't want to execute.

You can easily fix this problem when you change the extraction operator in myfile >> string1 with getline(myfile, string1); because getline will leave an empty input buffer.

But then you will have another problem. The while loop will execute only once again because there is \n left in the input buffer so you'll need a myfile.ignore(numeric_limits<streamsize>::max(), '\n');.

Your final code should lool like this:

int main ()
{
    ifstream myfile;
    string string1;
    string string2;
    int int1;

    myfile.open("filename.txt");

    getline(myfile, string1);

    while(getline(myfile, string2) && myfile >> int1)
    {
        myfile.ignore(numeric_limits<streamsize>::max(), '\n');
        cout << "read string " << string2 << " and int " << int1 << endl;
    }

    return 0;
}

I hope this helps you.

Upvotes: 1

Joseph Mansfield
Joseph Mansfield

Reputation: 110658

Extraction with >> into a std::string will read up until the next whitespace. So yes, it'll only extract a single word from the line. If you want to extract the entire line, use std::getline. You can incorporate it as follows:

while(std::getline(myfile, string2) &&
      myfile >> int1) {
    myfile.ignore();
    cout << "read string " << string2 << "and int " << int1 << endl;
}

The ignore is required because extraction into the int will leave the following \n character in the stream. This needs to be removed for the following std::getline in the next iteration to succeed.

Upvotes: 0

Related Questions