【问题标题】:Need help using getline in a file在文件中使用 getline 需要帮助
【发布时间】:2017-07-06 01:58:51
【问题描述】:

我在显示输出时遇到问题。总是有额外的行被打印。我做了一些研究,结果证明这是因为我的 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

唯一正确打印的是第一行。 (注)我必须使用结构。

【问题讨论】:

  • 在阅读时测试错误,而不是在阅读 16 次之前测试一次,因为所有错误都可能失败。您在混合 getline 和 &gt;&gt; 时也会遇到一些麻烦,而不会忽略掉剩余的换行符。由于您的价格是一个字符串,您不妨阅读整行并简化您的生活。你也可以考虑一个数组。
  • 你不能在 getline 之后使用 eof() ,因为那是文件的结尾。您可能应该检查 EOL 或在 getline() 中使用 \n 作为分隔符并使用 get line() 而不是 >>
  • 这是一些关于混合getline&gt;&gt; 的好读物。 stackoverflow.com/questions/21567291/…
  • @RetiredNinja 感谢您的帮助,我会阅读更多内容。
  • @SurajS 我将更新我的代码并再次发布。谢谢

标签: c++ fstream getline


【解决方案1】:

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

while(infile)

这会检查输入流是否已经进入了失败状态。

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

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

如果文件已经遇到文件结束条件,则再次显式检查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() 与格式化的输入操作 &gt;&gt; 操作符混合在一起。

这样的组合是脆弱的,并且有几种不明显的故障模式,as explained here,所以我不再重复了;有关更多信息,请参阅这个较早的问题。

虽然有一些方法可以正确地做到这一点,但重写代码以仅使用 std::getline()&gt;&gt; 运算符来读取所有内容会更容易,直到您完全了解如何正确组合未格式化和格式化输入操作。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-31
    • 2010-12-17
    • 2015-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多