C++文件读取问题
C++ file reading problems
尝试使此代码正常工作时遇到问题。这是我的文本文件:
Raisin Bran
3.49
300
Milk
1.49
200
White Bread
2.49
100
Butter
2.49
100
Grape Jelly
1.09
50
这是我的部分代码:
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);
出于某种原因,它只读取单词 "raisin" 和后面的数字。这是因为第一行有两个词,而不是一个,而我的 inFile 一次只做一个词。如果我将这两个词组合成一个词,整个代码就可以正常工作(例如,Raisin Bran 变成 RaisinBran)。有没有办法让我做到这一点而不用把所有的东西都变成一个词?
当我把第一行变成getline(inFile, tempy)
第一行打印,但是数字只是一遍又一遍地重复。
尝试使用带有 getline()
的字符串而不是数组。
int main() {
string line;
if (getline(cin,line)) {
//your code
}
}
你的问题是你混合了 std::getline()
和 operator>>
。这通常会导致问题,因为一个人删除新行而另一个人离开它。
问题 1:
inFile >> tempy; // Only reads one word.
解决方案使用std::getline
std::getline(inFile, tempy);
问题 2
std::getline() 函数假定您位于行首。当您从第一行开始时,这适用于第一条记录。
但是因为您正在使用 operator>>
读取数字,所以这些数字会在输入流中留下尾随的 '\n'。因此,在阅读了前两个数字 3.49
和 300
之后,您在 strem 上留下了一个 '\n'。
流看起来像这样:
\nMilk\n1.49\n200\nWhite Bread\n2.49...(etc)
如果您知道尝试使用 std::getline() 读取下一个项目(牛奶)的名称,您将在 tempy
中得到一个空值(因为输入的下一个字符是新行,所以它认为你有一个空行,只是删除 '\n'
)。下一次读取尝试读取一个数字,但如果找到的是一个字符串 Milk
,这会使流处于错误状态,它将拒绝读取更多值。
简单的解决方案。读取第二个数字后,读取并丢弃该行的其余部分。
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).
更好的解决方案:不要混用 std::getline()
和 operator>>
。将每一行读入一个字符串然后解析该字符串(可能使用 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()
下一步
删除设置函数并为 Inventory class.
编写自定义 operator>>
尝试使此代码正常工作时遇到问题。这是我的文本文件:
Raisin Bran
3.49
300
Milk
1.49
200
White Bread
2.49
100
Butter
2.49
100
Grape Jelly
1.09
50
这是我的部分代码:
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);
出于某种原因,它只读取单词 "raisin" 和后面的数字。这是因为第一行有两个词,而不是一个,而我的 inFile 一次只做一个词。如果我将这两个词组合成一个词,整个代码就可以正常工作(例如,Raisin Bran 变成 RaisinBran)。有没有办法让我做到这一点而不用把所有的东西都变成一个词?
当我把第一行变成getline(inFile, tempy)
第一行打印,但是数字只是一遍又一遍地重复。
尝试使用带有 getline()
的字符串而不是数组。
int main() {
string line;
if (getline(cin,line)) {
//your code
}
}
你的问题是你混合了 std::getline()
和 operator>>
。这通常会导致问题,因为一个人删除新行而另一个人离开它。
问题 1:
inFile >> tempy; // Only reads one word.
解决方案使用std::getline
std::getline(inFile, tempy);
问题 2
std::getline() 函数假定您位于行首。当您从第一行开始时,这适用于第一条记录。
但是因为您正在使用 operator>>
读取数字,所以这些数字会在输入流中留下尾随的 '\n'。因此,在阅读了前两个数字 3.49
和 300
之后,您在 strem 上留下了一个 '\n'。
流看起来像这样:
\nMilk\n1.49\n200\nWhite Bread\n2.49...(etc)
如果您知道尝试使用 std::getline() 读取下一个项目(牛奶)的名称,您将在 tempy
中得到一个空值(因为输入的下一个字符是新行,所以它认为你有一个空行,只是删除 '\n'
)。下一次读取尝试读取一个数字,但如果找到的是一个字符串 Milk
,这会使流处于错误状态,它将拒绝读取更多值。
简单的解决方案。读取第二个数字后,读取并丢弃该行的其余部分。
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).
更好的解决方案:不要混用 std::getline()
和 operator>>
。将每一行读入一个字符串然后解析该字符串(可能使用 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()
下一步
删除设置函数并为 Inventory class.
编写自定义operator>>