❥关于C++之文件结尾及处理
如果输入来自于文件,则可以使用一种功能更强大的技术——检测文件尾(EOF)。C++输入工具和操作系统协同工作,来检测文件尾并将这种信息告知程序。检测EOF时将关闭对输入的进一步读取。乍一看,读取文件中的信息似乎同cin和键盘输入没什么关系,但其实存在两个相关的地方。首先,很多操作系统(包括Unix、Linux和Windows命令提示符模式)都支持重定向,允许用文件替换键盘输入。例如,假设在Wind
如果输入来自于文件,则可以使用一种功能更强大的技术——检测文件尾(EOF
)。C++输入工具和操作系统协同工作,来检测文件尾并将这种信息告知程序。检测EOF
时将关闭对输入的进一步读取。
很多操作系统都允许通过键盘来模拟文件尾条件。在Unix中,可以在行首按下Ctrl+D来实现;在Windows命令提示符模式下,可以在任意位置按Ctrl+Z+Enter。有些C++实现支持类似的行为,即使底层操作系统并不支持。键盘输入的EOF概念实际上是命令行环境遗留下来的。然而,用于Mac的Symantec C++模拟了UNIX,将Ctrl+D视为仿真的EOF。Metrowerks Codewarrior能够在Macintosh和Windows环境下识别Ctrl+Z。用于PC的Microsoft Visual C++、Borland C++ 5.5和GNU C++ 都能够识别行首的Ctrl + Z,但用户必须随后按下回车键。总之,很多PC编程环境都将Ctrl+Z视为模拟的EOF,但具体细节(必须在行首还是可以在任何位置,是否必须按下回车键等)各不相同。
检测到EOF
后,cin将两位(eofbit
和failbit
)都设置为1。可以通过成员函数eof()来查看eofbit是否被设置;如果检测到EOF,则cin.eof()将返回bool值true,否则返回false。同样,如果eofbit或failbit被设置为1,则fail()成员函数返回true,否则返回false。注意,eof()和fail()方法报告最近读取的结果;也就是说,它们在事后报告,而不是预先报告。因此应将cin.eof()或cin.fail()测试放在读取后,下面的程序中的设计体现了这一点。它使用的是fail(),而不是eof(),因为前者可用于更多的实现中。
#include <iostream>
int main() {
using namespace std;
char ch;
int count = 0;
cin.get(ch);
while (cin.fail() == false) { // test for EOF(放在读取后!)
cout << ch;
++count;
cin.get(ch);
}
cout << endl << count << " characters read\n";
return 0;
}
|The green bird sings in the winter.<Enter>
The green bird sings in the winter.
|Yes, but the crow flies in the dawn.<Enter>
Yes, but the crow flies in the dawn.
^Z<Enter>
73 characters read
^Z
是从键盘<Ctrl>+<Z>
完成的。统计出的73个字符是包含前2个<Enter>换行符’\n’的,但不包含^Z(EOF)及后面的内容。
然而,istream类提供了一个可以将istream对象(如cin)转换为bool值的函数;当cin出现在需要bool值的地方(如在while循环的测试条件中)时,该转换函数将被调用。另外,如果最后一次读取成功了,则转换得到的bool值为true;否则为false。这意味着可以将上述while测试改写为这样:
while(cin) // while input is successful
这比!cin.fail()
或!cin.eof()
更通用,因为它可以检测到其他失败原因,如磁盘故障。
示例:输入空行结束
#include <iostream>
const int ArSize = 10;
void strcount(const char* str);
int main() {
using namespace std;
char input[ArSize];
char next;
cout << "Enter a line:\n";
cin.get(input, ArSize);
while (cin) {
cin.get(next);
while (next != '\n')// string didn't fit!
cin.get(next);// dispose of remainder
strcount(input);// strcount函数计算input的字符数,并打印输出
cout << "Enter next line (empty line to quit):\n";
cin.get(input, ArSize);
}
cout << "Bye";
return 0;
}
Enter a line:
|abcdef<Enter>
"abcdef" contains 6 characters
Enter next line (empty line to quit):
|<Enter>
Bye
即,空行,使得cin为false,结束循环。
当前C++的做法是:当cin.get()(而不是cin.getline())读取空行后将设置失效位(failbit)。这意味着接下来的输入将被阻断,但可以用这条命令来恢复输入:cin.clear();。
直接用EOF
判断结尾:
#include <iostream>
int main(void) {
using namespace std;
int ch; // should be int, not char!!!
int count = 0;
while ((ch = cin.get()) != EOF) { // test for end-of-file
cout.put(char(ch));
++count;
}
cout << endl << count << " characters read\n";
return 0;
}
|abc<Enter>
abc
|def<Enter>
def
^Zxyz<Enter>
8 characters read
从文本文件输入:
乍一看,读取文件中的信息似乎同cin和键盘输入没什么关系,但其实存在两个相关的地方。首先,很多操作系统(包括Unix、Linux和Windows命令提示符模式)都支持重定向,允许用文件替换键盘输入。例如,假设在Windows中有一个名为gofish.exe的可执行程序和一个名为fishtale的文本文件,则可以在命令提示符模式下输入下面的命令:gofish < fishtale
假设上述程序生成的可执行文件为Hello.exe,将输入源转为File文件“file.txt”,命令行运行:Hello < file.txt
21个字符,包含了第一行文本的换行符。
更多推荐
所有评论(0)