为什么我的输入文件的最后一行运行两次?
Miller Andrew 65789.87 5
Green Sheila 75892.56 9
Sethi Amit 74900.50 6.1
ifstream inFile;
ofstream outFile;
string laastName;
string firstName;
double salary;
double percent;
double new Salary;
double increase;
inFile.open("Ch3_Ex6Data.txt");
outFile.open("Ch3_Ex6Output.dat");
while(!inFile.eof()) {
inFile >> lastName;
inFile >> firstName;
inFile >> salary;
inFile >> percent;
percent /= 100;
increase = salary * percent;
newSalary = increase + salary;
outFile << firstName << " " << lastName << " ";
outFile << setprecision(2) << fixed << newSalary << endl;
}
inFile.close();
outFile.close();
return 0
}
输出文件
Andrew Miller 69079.36
Sheila Green 82722.89
Amit Sethi 79469.43
Amit Sethi 74946.19
我的问题是,为什么是最后一行获得输出两次,为什么它比第一个不同?我不明白为什么循环继续。文件标记的结尾是否不打?我能够通过放入一个索引变量并在while循环中放入第二个条件来对其进行硬编码,通过说& &小于索引,但我感觉好像我不应该那样做。
您使用
lastName
但你申报laastName
所以去除a
和谨慎。double new Salary
:这是什么? - 我认为你的意思是:double NewSalary
如果是这样,请阅读一本关于在C++中命名变量的有用书,因为你故意搞砸了。while(!inFile.eof())
不建议如此放弃使用它。在
main
的末尾缺少分号;
。-
你的代码如下:
int main() { ifstream inFile; ofstream outFile; string lastName; string firstName; double salary; double percent; double newSalary; double increase; inFile.open("Ch3_Ex6Data.txt"); outFile.open("Ch3_Ex6Output.dat"); while(inFile >> lastName >> firstName >> salary >> percent){ percent /= 100; increase = salary * percent; newSalary = increase + salary; outFile << firstName << " " << lastName << " "; outFile << setprecision(2) << fixed << newSalary << endl; } inFile.close(); outFile.close(); return 0; }
您不检查是否有读取成功。你输出的东西是否读取失败。
您的代码似乎预计eof()
可以预测未来的阅读是否会成功。但它并不能预测未来。未来的阅读仍然会失败。
上一次通过循环,所有的读取操作失败,所以所有的变量仍然有它们的原始值。然后再输出最后一行。然后你最后检查错误(呼叫eof()
在循环中的时间),但它为时已晚。
相反,为什么不只是检查你的读取是否成功?这就是你真正想知道的。
顺便说一句,这是一个非常常见的错误,出现在许多不同的环境中。这个错误的关键在于你试图检查所有必要的条件,以便成功,然后假设事情会成功,因为你检查了它可能会失败的每一个方式。至少有三个原因,这是一个糟糕的主意。首先,这通常是浪费精力。其次,当您检查和尝试操作时,事情可能会发生变化。第三,你可能错过了其中一种失败的方式。
在这里,所有三个原因适用。
它保留了前一次迭代的值。 –
当输入操作到达流结束时(如:读取最后一行),但当输入操作尝试在流结束后读取数据时,eofbit不会被设置(如:尝试在没有剩余数据时读取数据,因为文件流的末尾已到达)。
这意味着完成读取文件的最后一行确实是而不是设置文件结束位,而eof()
仍然是错误的。因此你的程序运行到下一个循环周期,并进行后,才在该行
inFile >> lastName;
下一个读操作,eofbit被设定。 最后一行打印两次,因为上一次循环迭代过程中的所有读取操作都会失败,并且变量仍然具有前一次循环迭代的值。
编辑: 为了防止您可以检查读取操作是否成功,例如,通过在循环中使用inFile.good()
:
while(!inFile.eof()) {
inFile >> lastName;
inFile >> firstName;
inFile >> salary;
inFile >> percent;
//check whether no errors occurred during the input operations
if (!inFile.good())
{
//input failure, leave the loop
break;
}
percent /= 100;
increase = salary * percent;
newSalary = increase + salary;
outFile << firstName << " " << lastName << " ";
outFile << setprecision(2) << fixed << newSalary << endl;
}
的问题是,eof
没有做什么,你认为它。
想象一下,你在地板上行走,铺瓷砖后,拿起地板上的东西,放在你的口袋里,露出(打印)你口袋里的内容。
当你把脚放在最后一块瓷砖上时,地板还没有“结束”,你的鼻子仍然安全。你还没有砸墙。填满口袋并打印出来。
eof
然后,告诉你你的鼻子何时坏了,而不是当瓷砖是最后的时候。
所以,你在最后一块瓷砖上,检查一下你的鼻子,找到它,然后向前走一步。你的鼻子现在流血了,没有什么可以偷看到我们的口袋里,而你的口袋里仍然包含着......他们以前的东西。
您打印口袋的内容(再次),并检查您的鼻子。它坏了:你退出。
来解决这个问题的习惯的方法是这样的一个:
while(inFile >> lastName
>> firstName
>> salary
>> percent)
{
//all your computation here
}
我觉得你应该自己为什么理解。
臭名昭著',而(!inFile.eof()){'错误! –
你可以使用这个:'while(inFile >> lastName >> firstName >> salary >> percent)'{} – Raindrop7