0

I am trying to read characters separated by white space from an input textile in C++. I've successfully opened the file and been able to iterate through it. However, whenever I try to assign variables from the characters in the file, the lines seem to be cleared. The first line's variables are set correctly, but are not after the first line. I am not sure if I am accessing the infile incorrectly, if there is a flag I am missing, or if there is a better method of approaching accessing the characters.

Code:

int lineNumber = 0,*linesMaxVal = new int[lineCount];
string line;
while (getline(infile, line)) {

    cout << "line # is " << lineNumber << " line val is: " << "'" << line << "'" << endl;

    int x1,x2,x3,x4,x5,max;
    infile >> x1 >> x2 >> x3 >> x4 >> x5;
}

If the line "infile >> x1 >> x2 >> x3 ... etc" is removed, the output is as follows (correct)

line # is 0 line val is: '0 0 0 0 0'
line # is 0 line val is: '1 2 3 4 5'
line # is 0 line val is: '5 4 3 2 1'
line # is 0 line val is: '5 100 1000 10000 10500'
line # is 0 line val is: '99999 99999 99998 99999 99999'
line # is 0 line val is: '-1 0 0 0 -1'
line # is 0 line val is: '-9999 -9999 -9998 -9999 -9999'
line # is 0 line val is: '50 1234 457 789 7'
line # is 0 line val is: '123240 -124 -453 234 -99999'
line # is 0 line val is: '234 235 -109 0 12'
line # is 0 line val is: '777 987 234 345 111'
line # is 0 line val is: '12 0 -19 27 19'
line # is 0 line val is: '0 0 0 0 0'
line # is 0 line val is: '-99 -900 45 20 10'
line # is 0 line val is: '13 -56 99 123 90'
line # is 0 line val is: '0 0 1 -11 -1'
line # is 0 line val is: ''

Otherwise, if the infile line is left in and the variables are defined, the output is as follows.

line # is 0 line val is: '0 0 0 0 0'
line # is 0 line val is: ''
line # is 0 line val is: ''
line # is 0 line val is: ''
line # is 0 line val is: ''
line # is 0 line val is: ''
line # is 0 line val is: ''
line # is 0 line val is: ''
line # is 0 line val is: ''
line # is 0 line val is: ''
line # is 0 line val is: ''
line # is 0 line val is: ''
line # is 0 line val is: ''
line # is 0 line val is: ''
line # is 0 line val is: ''
line # is 0 line val is: ''

Any help is appreciated!

r3mus n0x
  • 5,400
  • 1
  • 8
  • 30
John Harding II
  • 544
  • 1
  • 6
  • 20

1 Answers1

1
infile >> x1 >> x2 >> x3 >> x4 >> x5;

Reads all of the numbers on the line but leaves the newline character in the stream.

Then you go back to the head of your loop and run:

getline(infile, line)

Which immediately sees a newline, so it gives you an empty string, eats the newline and moves on.

The big issue here is that the extraction operator (>>) leaves the whitespace it stops at in the stream (in this case a newline), while getline eats whatever delimeter it stops on. Mixing the two can cause little hiccups like this.

One possible fix could be to add an ignore after your extraction operators to get the newline out of the stream.


After some talk in chat, it looks like you want to loop through the file and find the largest value on each line. I'd suggest using a vector to store each line's values and using the algorithm library to find the max:

//Our temp vector. It'll hold a line worth of ints
vector<int> line(5);

while(true) { //one loop = one line

    //Loop and read 5 ints (one line's worth) into the vector 
    for(int x = 0; x < 5 && infile >> line.at(x); x++) { }

    if(!infile) { break; } //if we read through everything, we're done!

    //find the biggest value in the vector
    int biggest = *max_element(line.begin(), line.end());

    //Do some things with it...
    cout << "Biggest is: " << biggest << endl;
}

For a working demo, see here: ideone

scohe001
  • 13,879
  • 2
  • 28
  • 47
  • Gotcha, that makes sense. How would an ignore flag be used in this context? – John Harding II Oct 25 '18 at 16:25
  • @JohnHardingII you could do `infile.ignore(std::numeric_limits::max(), '\n')`. See here for more: https://en.cppreference.com/w/cpp/io/basic_istream/ignore – scohe001 Oct 25 '18 at 16:27
  • Hmm, that's definitely an improvement as the variables are being filled now, however it is skipping every other line which is undesired. – John Harding II Oct 25 '18 at 16:43
  • @JohnHardingII yes, because you're reading that line into `x1, x2, ...` and then not doing anything with it. So you're actually reading in every line, you're just only printing every *other* line. – scohe001 Oct 25 '18 at 16:44
  • Forgive me if I'm misunderstanding, but after running a few more tests it does not seem to be reading every line into the variables, instead actually skipping them. Is there a step I'm missing in order to preserve every line? – John Harding II Oct 25 '18 at 16:52
  • @JohnHardingII once you've extracted from the stream, you can't read them from the stream again. `getline()` will extract a full line until it hits a newline. `infile >> x1 >> x2 >> ...` will extract a full line (except the newline at the end). Every loop you're extracting two lines from the stream but only printing the one you got from `getline` – scohe001 Oct 25 '18 at 16:55
  • Oh, okay. What would bet the best method of using the second line that is being extracted but is currently unused? – John Harding II Oct 25 '18 at 17:03
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/182516/discussion-between-scohe001-and-john-harding-ii). – scohe001 Oct 25 '18 at 17:04