需要帮助在文件中使用getline

时间:2017-07-06 01:58:52

标签: c++ fstream getline

我在显示输出时遇到问题。总是有额外的线条被打印出来。我做了一些研究,结果证明它是因为我的getline。我也为格式

道歉
#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;
}

文件中的内容

Plain Eggs
1.45
Bacon and Eggs
2.45
etc.

我尝试使用

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

这是我的输出

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

只有正确打印的东西才是第一行。 (注)我必须使用结构。

1 个答案:

答案 0 :(得分:0)

所示代码中至少存在三个主要问题。第一个没有正确检查文件结束条件:

while(infile)

检查输入流 是否已进入失败状态。

在阅读文件中的最后一行后,您的输入流还没有失败。到目前为止,一切都完全符合计划。

因此,在文件的最后一行之后,此条件仍将评估为true,再次运行循环。当然,它会悲惨地失败。

如果文件 已经 ,则明确检查if (infile.eof())是否会遇到文件结束条件。

您可能想要做的是尝试开始阅读文件中的下一行,如果失败,那么您已经达到了它的结束:

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

但是,单凭这一点,不会解决所有问题。

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

这是将未格式化的输入操作std::getline()与格式化的输入操作>>运算符混合。

这种组合很脆弱,有几种非明显的失败模式,as explained here,所以我不会重复这一点;请参阅前面的问题以获取更多信息。

虽然有一些方法可以正确执行此操作,但您可以更轻松地重写代码,仅使用std::getline()>>运算符来阅读所有内容,直到您完全理解如何正确组合未格式化和格式化的输入操作。

最后一个问题是一个小问题。显示的代码无法正确处理不完整的输入和错误检查。如图所示,只要它成功读取一组数据中的第一部分,它就会假定其余数据存在。您应该验证是否正确检查了每个输入操作(无论您选择使用格式化还是未格式化的输入操作)是否成功。