1

I'm trying to read an input file formatted with two numbers on a line and store the first number in the line in one vector and the second number in another vector.

Every part of my code works fine except for the actual reading of the file.

I have put couts all over the place and it looks like while my file is being opened, it's not being read, so my vectors keep getting filled until I run out of memory.

Here's the part of my code that reads the file:

cout << "Input Filename: ";
cin >> input;
//open input file
inputdata.open(input.c_str());
if(!inputdata){
cerr << "Error: Unable to open file!" << endl;
}

while(!inputdata.eof()){
    counter++;
    hold = 0;
    if(counter > 0){
        inputdata >> hold;
        //cout << hold << endl;
        if(counter%2 != 0)
            data.push_back(hold);
        else
            weight.push_back(hold);
    }
}

(where counter is an integer initialized at -1 since there is a one-word title at the beginning of the input file that I need to ignore).

I know using .eof() is frowned upon, but it won't actually affect what I'm doing.

Does anyone see a problem in my code or why it wouldn't be reading the file?

Will
  • 11
  • 1
  • 3
  • Please post more code prior to the while loop. –  Jul 22 '11 at 13:41
  • Don't rely on eof. It is probably that hold is reading -1 ( which is actually an EOF) but it isn't setting the eof bit, it happens with formatted i/o on file. Either add if ( holder == -1) break; or better yet try to use get to read the file.( using get will make the eof work). – xeon111 Jul 22 '11 at 13:45
  • 1
    Try testing `inputdata` instead of `!inputdata.eof()`. That would also test for problems other than eof. – Juraj Blaho Jul 22 '11 at 13:45
  • @ 0A0D done @xeon I tried couting inputdata but it just returns 0 every time – Will Jul 22 '11 at 13:49
  • @Will wait you said one word title , with emphasis on the word part. use a string to read the word, your input is failing there, you are trying to input a word while the input expected is int. – xeon111 Jul 22 '11 at 13:53
  • We can't decide what's going wrong, when we do not know the variable types. So please add their definition. – René Richter Jul 22 '11 at 13:54
  • See also [this question](http://stackoverflow.com/questions/5837639/eof-bad-practice) for why it is a bad idea to have an input loop check for EOF. – sbi Jul 22 '11 at 14:07

3 Answers3

1

Why not use:

std::string firstword;
inputdata >> firstword; // or std::getline(inputdate, firstword);

while (inputdata >> w >> d)
{
  weight.push_back(w);
  data.push_back(d);
}

It's much cleaner since data and weight go in pairs (maybe I changed w and d).

René Richter
  • 3,839
  • 3
  • 34
  • 42
1

It is wrong to use .eof() in a while loop. For example,

while(!inputdata.eof()){
   ... 
}

Wrong.

This is the correct use.

if (!(cin >> foo)) {
  if (cin.eof()) {
    cout << "read failed due to EOF\n";
  } else {
    cout << "read failed due to something other than EOF\n";
  }
}

Additionally, at the C++ FAQ, in Section 15.5 it says "Why does my input seem process past the end of a file?"

Because the eof state may not get set until after a read is attempted past the end of file. That is, reading the last byte from a file might not set the eof state. E.g., suppose the input stream is mapped to a keyboard — in that case it's not even theoretically possible for the C++ library to predict whether or not the character that the user just typed will be the last character.

You also need to check if your fstream is properly open by doing this,

if (inputdata.is_open()) { /* ok, proceed with output */ }

Doing if(!inputdata) is not the proper check.

Community
  • 1
  • 1
0

"since there is a one-word title at the beginning of the input file that I need to ignore" That might be problematic. Trying to read a text with ints or floats is asking for trouble.

If this word is on a seperate line, try this: http://www.cplusplus.com/reference/iostream/istream/getline/

Else, try to read the first word with a temporary string.\

holgac
  • 1,509
  • 1
  • 13
  • 25