十分邪门的问题,花了我一晚上的时间
代码
#include<iostream>
#include<string>
#include<fstream>
using namespace std;
int main()
{
string str;
ifstream inFile("test.txt");
int i= 0;
while(inFile.good()&&!inFile.eof()) {
i++;
cout << i << endl;
inFile >> str;
cout << str << endl;
}
inFile.close();
return 0;
}
输出
-bash-4.1$ ./a.out
1
banana
2
bread
3
wine
4
wine
文本文件
-bash-4.1$ more test.txt
banana
bread
wine
以前都是很正常的,不知道为啥这次inFile在遇到文件的eof时候没有停下,有多循环了一次,导致i的值为4,还输出了最后的一个wine
ps:这是我大程序的debug里的一小块,那个程序更奇妙,输出不仅多执行了一个while循环,执行还“卡”在那了,必须用ctrl+c 才能退出
这是为啥呢?应该怎样改?谢谢大虾们了
[解决办法]
fstream 中的 eofbit 标记是在尝试读取文件结尾时才设立的.
读取完最后一个数据后,fstream 仍处于正常状态,所以下一次 while 判断不会跳出,再次 fin>>str 时,fstream 发现没有数据可读,此时才会设立 failbit。但由于已进入循环,虽然未读数据,str 仍保留上次的值。
解决方法改变循环条件即可:
- C/C++ code
while( inFile >> str ) { i++; cout << i << endl; //inFile >> str; cout << str << endl; }
[解决办法]
和操作系统相关,
在windows下:
while(inFile.good()&&(!inFile.eof()))
{
i++ ;
inFile >> str;
std::cout<<str<<std::endl;
}
inFile.close();
在linux下:
while(inFile.good())
{
i++ ;
inFile >> str;
if(inFile.eof())
{
break;
}
std::cout<<str<<std::endl;
}
inFile.close();
[解决办法]
不要使用
while (条件)
更不要使用
while (组合条件)
要使用
while (1) {
if (条件1) break;
//...
if (条件2) continue;
//...
if (条件3) return;
//...
}
因为前两种写法在语言表达意思的层面上有二义性,只有第三种才忠实反映了程序流的实际情况。
典型如:
下面两段的语义都是当文件未结束时读字符
whlie (!feof(f)) {
a=fgetc(f);
//...
b=fgetc(f);//可能此时已经feof了!
//...
}
而这样写就没有问题:
whlie (1) {
a=fgetc(f);
if (feof(f)) break;
//...
b=fgetc(f);
if (feof(f)) break;
//...
}
类似的例子还可以举很多。
[解决办法]
楼主是什么环境?编译器的版本是多少?如果你是用的标准写法写的,有谁写过类似的代码吗?
我看来,你又何必去简就繁呢.
- C/C++ code
#include<iostream>#include<string>#include<fstream>using namespace std;int main(){ string str; ifstream inFile("test.txt"); int i= 0; while(inFile >> str) { i++; cout << i << endl; //inFile >> str; cout << str << endl; } inFile.close(); return 0;}