0

Im having issues displaying the output. There is always and extra line being printed. I did some research and it turns out that its because my getline. Also I apologize for the format

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

struct menuItemType
{
string menuItem;
double menuPrice;
};

int main()
 {
 menuItemType plainEgg;
 menuItemType baconEgg;
 menuItemType muffin;
 menuItemType frenchToast;
 menuItemType fruitBasket;
 menuItemType cereal;
 menuItemType coffee;
 menuItemType tea;

ifstream infile;
infile.open("Ch9_Ex5Data.txt"); 

while(infile)
{
getline(infile,plainEgg.menuItem);
infile >> plainEgg.menuPrice;

getline(infile,baconEgg.menuItem);
infile >> baconEgg.menuPrice;

getline(infile,muffin.menuItem);
infile >> muffin.menuPrice;

getline(infile,frenchToast.menuItem);
infile >> frenchToast.menuPrice;

getline(infile,fruitBasket.menuItem);
infile >> fruitBasket.menuPrice;

getline(infile,cereal.menuItem);
infile >> cereal.menuPrice;

getline(infile,coffee.menuItem);
infile >> coffee.menuPrice;

getline(infile,tea.menuItem);
infile >> tea.menuPrice;

cout << plainEgg.menuItem << plainEgg.menuPrice << endl;
cout << baconEgg.menuItem << baconEgg.menuPrice << endl;
cout << muffin.menuItem << muffin.menuPrice << endl;
cout << frenchToast.menuItem << frenchToast.menuPrice << endl;
cout << fruitBasket.menuItem << fruitBasket.menuPrice << endl;
cout << cereal.menuItem << cereal.menuPrice << endl;
cout << coffee.menuItem << coffee.menuPrice << endl;
cout << tea.menuItem << tea.menuPrice << endl;
}
infile.close();

return 0;
}

Contents in the file

Plain Eggs
1.45
Bacon and Eggs
2.45
etc.

I tried using

if (infile.eof())
    cout << endl;

this is my output

Plain Egg1.45   // <-- this is the only correct output
Bacon
and Egg2.45
Muffin
0.99
French
Toast1.99
Fruit
Basket2.49
Cereal
0.69
Coffee
0.50
Tea
0.75

Only thing that printed correctly was the very first line. (Note)I have to use structure.

Rotary
  • 1
  • 1
  • Test for errors when reading, not once before you read 16 times when all of them could fail. You're also going to have some trouble mixing getline and `>>` without some ignores to eat the leftover newlines. Since your price is a string you might as well just read the whole line and simplify your life. You might also think about an array. – Retired Ninja Jul 06 '17 at 02:02
  • You cannot use eof() after getline cause that's end of file. You should probably check for EOL or use a \n as a delimiter in getline() and use get line() instead of >> – Suraj S Jul 06 '17 at 02:05
  • This is some good reading about mixing `getline` and `>>`. https://stackoverflow.com/questions/21567291/why-does-stdgetline-skip-input-after-a-formatted-extraction – Retired Ninja Jul 06 '17 at 02:06
  • @RetiredNinja Thank you for your help I will read more. – Rotary Jul 06 '17 at 02:14
  • @SurajS I will update my code and post it again. Thanks – Rotary Jul 06 '17 at 02:15
  • Rotary, at this point you have an answer which covers all of the main errors in your code. Significantly changing the code in your post may render this answer incomprehensible. It would be better if you resolved your current issues and asked a new question based on further problems you encounter. By the way, you may find [`std::vector` to be extremely useful.](http://en.cppreference.com/w/cpp/container/vector) – user4581301 Jul 06 '17 at 02:18

1 Answers1

0

There are at least three major problems in the shown code. The first one is not properly checking for an end of file condition:

while(infile)

This checks if the input stream already entered a failed state.

After reading the last line in your file, your input stream hasn't failed yet. Everything, up until point, has went exactly according to plan.

So, after the last line in the file, this condition will still evaluate to true, running the loop one more time. Of course, it will fail miserably.

And explicitly checking if (infile.eof()) will, again, if the file has already encountered an end-of-file condition.

What you probably want to do is to try to start reading the next line from the file, and if it fails, then you've reached the end of it:

while (getline(infile,plainEgg.menuItem))
{
      // The code that reads the next set of items.

But this, alone, won't solve all of your problems.

getline(infile,plainEgg.menuItem);
infile >> plainEgg.menuPrice;

This is mixing an unformatted input operation, std::getline(), with a formatted input operation, the >> operator.

Such combination is fragile, and has several non-obvious failure modes, as explained here, so I won't repeat that; just see this earlier question for more information.

Although there are ways to do this correctly, it's going to be easier for you to rewrite your code to use only std::getline(), or the >> operator to read everything, until you fully understand how to correctly combine unformatted and formatted input operations.

The last problem is a minor quibble. The shown code fails to properly handle incomplete input, and error checking. As shown, as long as it successfully reads the first piece in a set of data, it assumes that the remaining data will be there. You should verify that every input operation (whether you choose to use formatted or unformatted input operations) is properly checked for success.

Sam Varshavchik
  • 84,126
  • 5
  • 57
  • 106