您的位置:首页 > 其它

关于输入流对象cin的get函数——测试结论总结

2011-06-14 12:29 246 查看
关于输入流对象cin的get函数——测试结论总结
测试用代码如下:
do
{
c = cin.get();
cout<<"现在得到的字符是"<<c<<(int)c<<endl;
}while(c != 'D' && c != EOF);

对于上述代码,我的目的是测试终止符EOF的情况。在MSDN Library中,可以得到这样的阐述:
istream::get
Visual Studio 6.0
In all cases, the delimiter is neither extracted from the stream nor returned by the function. The getline function, in contrast, extracts but does not store the delimiter.
翻译:在所有情况下,终止符既不可能从流中获取也不能由这函数(猜测:应该是get函数)得出。相反地,getline函数可以获得但不能存储终止符。
在实际的测试中,我使用了VC6.0、VC2008、GCC三种环境进行比较,具体结果如下:
Ø 在VC6.0和GCC(如果在GCC中,需要将include<stdio.h>)中,如果在输入“Ctrl + L”之前,已经输入了其它字符,例如“fjskdl^Zdsklfj”或者“fjskdl^Z”,那么程序会忽略^Z以及^Z以后的字符。如果在输入“Ctrl + L”之前,没有其它字符输入,例如“^Zdsklfj”或者“l^Z”,这时程序,直接退出。
Ø 在VC2008中测试,如果在输入“Ctrl + L”之前,已经输入了其它字符,例如“fjskdl^Zdsklfj”或者“fjskdl^Z”,那么程序会忽略^Z以后的字符,但不会忽略^Z,而是输出“”,输出其整数值为26。如果在输入“Ctrl + L”之前,没有其它字符输入,则同上。
这里猜测,如果在输入“Ctrl + L”之前,已经输入了其它字符,那么程序将忽略^Z以后的字符,否则,终止输入。而且终止输入后,将不能再进行输入操作(?)。
下面在推测中说明该实验结果:在输入“Ctrl + L”之后,程序首先结束输入流,然后返回一个EOF。所以,如果有下面的代码,
while(c != 'F')
{
c = cin.get();
cout<<"2_现在得到的字符是"<<c<<endl;
}




但是,如果将上面的while条件改为while(c != EOF),那么程序不循环,因为之前的while循环使c的值被赋值为EOF,所以程序将不进入第二个while循环。

解决该问题的一个方法是:使用cin.clear()来清除EOF标记。
该方法的获得来源于一篇博文:
http://hi.baidu.com/%C3%A8%D1%DB%D3%E3/blog/item/5d41a83ab045c22f96ddd807.html
这里摘录其中和本问题联系比较密切的内容,如下:
……………………
很多PC编程环境都将Ctrl+Z视为模拟的EOF,但是具体细节(必须在行首还是可以再任意位置,是否需要按下回车键等)各不相同。
如果检测到EOF,cin将两位(eofbit和failbit)都置为1.可以通过成员函数eof()来查看eofbit是否被设置了,如果检测搭配EOF,那么cin.eof()将返回bool值为true,否则为false。
同样,如果eofbit或者failbit被置为1,则fail()返回true。
注意:eof()和fail()方法报告最近读取的结果,也就是说它们在事后报告,而不是预先报告。因此应该将cin.eof() cin.fail()测试放在读取后。
……………………
cin方法检测到EOF时,将设置cin对象中一个指示EOF条件的标记,设置这个标记后,cin将不再读取输入,再次调用cin也不管用。对于文件输入,这是有道理的,因为程序不应该读取超过文件尾的内容。不过对于键盘输入,有可能使用模拟EOF来结束循环,但稍后需要读取其他输入。cin.clear()方法能够清除EOF标记,使输入继续进行。
……………………

程序将会进入一个死循环,其不能继续输入,如下:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息