1

I am having trouble reading in double values into an array from a file after the first iteration of the for loop, there is no more reading due to the newline character. How can I bypass this issue?

Sample of input file:

word

2.55

word <---as of now this will not read

5.66

file.open("productsIn.txt");
   if(!file.is_open()){
    cout << "Could not open file." << endl;
    return 1;
}
 if(file.is_open()){
    cout << "file open" << endl;
    for(int i = 0; i < MAX_COUNT; i++){
        getline(file, productName[i]);
        file >> prices[i];
        if(file.good()){
            cout << productName[i] << endl << prices[i] << endl;
        }
    }
 }
    file.close();
  • Not the problem, but the second `if` statement is redundant; if the file isn't open, the function returned because of the first `if`, and won't reach the code that tries to read from the file. Also, no need to call `file.close()`; the destructor for the `file` object will do that. – Pete Becker Sep 13 '16 at 15:05
  • 1
    Most likely [this](http://stackoverflow.com/questions/21567291/why-does-stdgetline-skip-input-after-a-formatted-extraction) is your problem but I would need to see a sample of the file contents to be sure. – NathanOliver Sep 13 '16 at 15:05
  • 1
    Mixing `getline` with formatted extractors is tricky. Keep using `getline` to read lines, and create a `std::istringstream` to read the doubles from the resulting `string` object. – Pete Becker Sep 13 '16 at 15:06
  • Could you show us a sample of your file so we could see what format you're trying to read here? It's hard to correct code when you don't know what the correct behavior should be. – Jerry Coffin Sep 13 '16 at 15:13

1 Answers1

1

If your data consists of alternating lines of names and prices like this:

item 1
1.50
item2
2.50
...

You can of course simply call another getline() after reading the float. It will read away the newline which is at the read position, and clear the dummy string argument which can be ignored. It kind of makes sense because you do read two lines, so you may need two getlines. (You could do without the getline() after the name because the formatted input for the price will skip whitespace; but I guess the EOL is the marker for "end of name", where a name may consist of more than one word.)

You can also use ignore or ws as suggested in this complete answer.

Because the data is actually line oriented it may be clearer to follow Pete Becker's suggestion and read all lines via getline(), parsing the ones which need it — like the prices — simply via a [i]stringstream.

Community
  • 1
  • 1
Peter - Reinstate Monica
  • 12,309
  • 2
  • 29
  • 52
  • I tried to use a getline() to read in the double value, however, it would not compile due to the fact that getline will not read doubles. is there a way around this? – user3688675 Sep 13 '16 at 16:17
  • Just call `getline()`again with a (dummy) string argument. The string will be empty after the call, because the read position is at the end of the current line, but the newline terminating the current line will be "digested" (i.e. the read position will be advanced behind it, to the first character of the next line) as a side effect of the `getline()`. – Peter - Reinstate Monica Sep 13 '16 at 16:44