0

I have an issue with the following code snippet.

I have a file referred to with the character array FileName. The file could be basically anything, but in my case it is a file the contains some irrelevant text on the first line and then some lines that start with 1 (one) in one case and 0 (zero) in many other cases. So, my file is something like:

iewbFLUW 82494HJF VROIREBURV.TEXT

0 TEST whatever something
0 TEST words and more
1 TEST something something
0 TEST oefeowif
...

The intention of the my code snippet is that it picks the line selected with 1 (one).

// the stream object for my file:
string FileName = "myFile.text";
ifstream input(FileName);

// parsing the first line
char comment[1000];
input.getline(comment, 1000, '\n');
cout << comment << endl;

// parsing the other lines
bool select=false;
while (!input.eof())
{
    input >> select;

    cout << select << endl;
    if(select){
    // do something
     }
}

However, although the FileName starts the second line with a 0 (zero), the variable select turns out to have value 1 right after the line input >> select;

How can this be?

Svalbard
  • 165
  • 1
  • 11
  • Please provide an [SSCCE](http://sscce.org). – NathanOliver Jun 01 '15 at 20:18
  • 5
    Using `while (!input.eof())` is wrong. Use `while (input >> select)` instead. – wilx Jun 01 '15 at 20:20
  • What do you mean by 0(zero)? An ascii or binary value? – marom Jun 01 '15 at 20:26
  • @NathanOliver: I just did. Hope this helps... – Svalbard Jun 01 '15 at 20:34
  • As you're attempting to extract a `bool` from an input stream, I'm curious how you perceive anything *besides* `1` or `0` being read, because that is exactly what will fail with your while-loop as-presented here. – WhozCraig Jun 01 '15 at 20:42
  • @WhozCraig yes that is of course true, and that is being taken care of. Sorry this is just a very small piece of a much larger project, and I forgot to include the code dealing with the rest of the line(s). My bad. My bad. – Svalbard Jun 01 '15 at 20:44

1 Answers1

0

The major problem with your code is that input >> select does not read a full line, but it stops at the first whitespace. You then read again what you believe is a bool from the next line, but which in fact is the next character from the first word in the line, so your stream ends up with a failbit set, and after that it's game over, you cannot successfully read from the stream again.

Read the whole line instead and use a std::stringstream to parse it, like

#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;

int main(void)
{
    string FileName = "test.txt";
    ifstream input(FileName);

    // parsing the first line
    std::string line;
    getline(input, line); // ignore first line
    bool select = false;
    while (getline(input, line)) // read line by line
    {
        std::istringstream ss(line); // map back to a stringstream
        ss >> select; // extract the bool
        if (select) { // process the line (or the remaining stringstream)
            cout << line; // display the line if it select == true
        }
    }
}

As mentioned in the comments, while(!input.eof()) is almost always wrong, see Why is iostream::eof inside a loop condition considered wrong?

Community
  • 1
  • 1
vsoftco
  • 52,188
  • 7
  • 109
  • 221
  • I was going to post an example with mixed operator >> and getline and ignore, but it's basically the same. I just avoid constructing stringstreams and avoid reading the ignored lines into memory. – Kenny Ostrom Jun 01 '15 at 21:12