前言
众所周知,C++的字符处理,尤其是输入输出,各种“读到文件结束”十分复杂。本文简单研究一下C++的各种字符输入方式。
由于C++提供了各种eof方法以供判断文件结尾,这就让人产生一种写类似这样代码的冲动:
while(eof){
读入什么东西;
}
而它在绝大多数情况下都是不能正常工作的。如果你改成这样:
while(true){
读入什么东西;
if(eof) break;
}
本文的目的就是对C++中各种主流读入方式,研究第一种方法为什么不行。
注意:本文所有测试都是在Windows环境下进行的。
C风格
C++中,字符输入输出有两种风格:一种是继承于C的,cstdio库中包含的各函数,另一种是C++风格的,iostream/fstream。
在cplusplus.com中,可以查到cstdio的如下成员函数:
getchar();fgetc();getc();
gets();fgets();
scanf();fscanf();
fread();
各种getchar
这里有三个函数:getchar,fgetc和getc。其中,fgetc和getc等价,它们都相当于给定了输入文件指针的getchar。
getchar函数的返回值是一个int:如果它成功读取字符,这个int就等于读取字符的ASCII码,否则就是EOF。这个EOF是编译器用宏定义的一个常数,也就是-1.
“读取不成功”包含你能想到的各种情况:比如读完了文件的最后一个字符,或文件不存在,或文件为空。
如果用getchar读取文件,能否用eof(注意这是小eof,那个大EOF是一个宏定义的常量)判断文件是否结束呢?答案是不行。不妨做个实验:
freopen("input.in","r",stdin);
while(!feof(stdin)){
cout<<(int)getchar()<<endl;
}
这个原因是为什么呢?在cstdio中,判断eof的方式是设一个标志(end of file indicator),这个标志平时是0,而当你用任何方式试图去读“文件结尾再下一位”的时候,它就会变成一个正值,表明文件结束。但是,如果一直用getchar,那么它站在文件末尾的时候并不知道下一位还有没有东西,那就