c++使用eof()最后一个字符读取两遍 先让我们看这样的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <iostream> #include <string> #include <stdio.h> #include <queue> #include <cstdio> #include <string.h> #include <fstream> #include <cstdlib> #include <iomanip> #include <algorithm> #include <cmath> using namespace std ;int main () { char a; ifstream file; file.open ("test.txt" ); if (!file.is_open()) { cout << "error" <<endl ; exit (1 ); } while (!file.eof()) { file >> a; cout << a; } return 0 ; }
test.txt文件内容为12345 可输出的结果却是 123455 为什么会出现这样的情况呢?
eof函数是在eofbit error state flag设为true时才返回1,而读取到’5’的时候eofbit error state flag仍然是flase,只有读取到’5’后面的文件结束符0xff时eof函数才会返回1,所以会多读取一次,而读取文件结束符并不会改变a的值,所以会多输出一次5。
解决办法时在这种情况下不要使用eof(),而是把file>>a作为while的判断条件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #include <iostream> #include <string> #include <stdio.h> #include <queue> #include <cstdio> #include <string.h> #include <fstream> #include <cstdlib> #include <iomanip> #include <algorithm> #include <cmath> using namespace std ;int main () { char a; ifstream file; file.open ("test.txt" ); if (!file.is_open()) { cout << "error" <<endl ; exit (1 ); } while (file >> a) cout << a; return 0 ; }
这样就没问题了.
奇怪的是,如果a不是char,而是其他类型的变量,使用eof()就不会出现这样的问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 int main () { int a; ifstream file; file.open ("test.txt" ); if (!file.is_open()) { cout << "error" <<endl ; exit (1 ); } while (!file.eof()) { file >> a; cout << a; } return 0 ; }
这样的结果也是12345,原因暂时不知道…
还有就是,不应该用eof()来判断文件是否为空
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 int main () { char a='1' ; ifstream file; file.open ("test.txt" ); if (!file.is_open()) { cout << "error" <<endl ; exit (1 ); } if (file.eof()) { cout << "file is empty." << endl ; return 0 ; } while (!file.eof()) { file >> a; cout << a; } return 0 ; }
如果test.txt存在但为空的话,结果会是1,因为这里没有对文件进行读取,所以eofbit error state flag并没有被设为true 如果要判断文件是否为空的话,应该使用peek()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 int main () { char a='1' ; ifstream file; file.open ("test.txt" ); if (!file.is_open()) { cout << "error" <<endl ; exit (1 ); } if (file.peek ()==EOF) { cout << "file is empty." << endl ; return 0 ; } while (!file.eof()) { file >> a; cout << a; } return 0 ; }
这样就没问题了