SKmuffin
SKmuffin

Reputation: 17

C++ file reading problems

Having a problem trying to get this code working. Here's my text file:

Raisin Bran
3.49
300
Milk
1.49
200
White Bread
2.49
100
Butter
2.49
100
Grape Jelly
1.09
50

Here's a part of my code:

    inFile >> tempy;
    grocery_items[k].set_item_name(tempy);
    inFile >> temp;
    grocery_items[k].set_item_price(temp);
    inFile >> stock;
    grocery_items[k].set_qty_on_hand(stock);

For some reason, it only reads the word "raisin" and the numbers after. This is because the first line has two words, not one and my inFile is only doing one word at a time. If I combine the two words into one word, the entire code works fine(for example, Raisin Bran becomes RaisinBran). Is there a way for me to be able to do this without making everything one word?

When I turn the first line into getline(inFile, tempy) The first line prints, however the numbers just repeat over and over again.

Upvotes: 1

Views: 160

Answers (2)

Loki Astari
Loki Astari

Reputation: 264331

Your problem is you are mixing std::getline() and operator>>. This usually causes problems as one removes the new line while the other leaves it.

Problem 1:

inFile >> tempy;  // Only reads one word.

Solution use std::getline

std::getline(inFile, tempy);

Problem 2

The std::getline() function assumes that you are at the beginning of the line. This works for the first record as you start on the first line.

But because you are using operator>> to read the numbers these leave the trailing '\n' on the input stream. So after reading the first two number 3.49 and 300 you are left with a '\n' on the strem.

The stream looks like this:

\nMilk\n1.49\n200\nWhite Bread\n2.49...(etc)

If you know try and read the name of the next item (Milk) with std::getline() you will get an empty value in tempy (as the next character on the input is a new line so it thinks tou have an empty line and just removes the '\n'). The next read tries to read a number but what if finds is a string Milk this puts the stream in a bad state and it will refuse to read more values.

Simple Solution. After reading the second number read and discard the rest of the line.

grocery_items[k].set_qty_on_hand(stock);
std::string skip
std::getline(inFile, skip);          // Note: there is a istream::ignore
                                     //       But I would have to look up the
                                     //       exact semantics (I leave that to
                                     //       you).

Better Solution: Don't mix std::getline() and operator>>. Read each line into a string then parse the string (maybe using stringstream).

std::string  numberString;
std::getline(inFile, numberString);
std::stringstream numberStream(numberString); // Might be overkill here.
numberStream >> tempy;                        // But it will work. Also look
                                              // at std::atoi()

Next Step

Get rid of the set functions and write a custom operator>> for Inventory class.

Upvotes: 4

Hassaan Salik
Hassaan Salik

Reputation: 413

Try Using string with getline() instead of array.

int main() {
   string line;
   if (getline(cin,line)) {
      //your code
   }
}

Upvotes: 0

Related Questions