std::cin 与 ctrl+z 配合使用时遇到的问题
2014-07-08 10:25
369 查看
《C++ Primer》第四版第一章1.4.4节,早早的教了我们如何利用cin读入未知数目的输入。
关键在于利用失败的cin>>返回0,一种触发失败的方式就是主动输入文件结束符,而Windows系统下输入文件结束符的方式,是按Ctrl + Z。
于是,实际使用中我碰到这样一个问题,请看以下代码:
这是一个二分查找程序的一部分,意图就不多解释了,可完整运行。
但是,你会发现运行结果有些意外,第二个cin>>target似乎完全不起作用,一旦ctrl+z结束第一个循环后,程序就直接结束了。
在网上搜索一些资料或者翻翻书,我们会发现,cin是维持着一系列状态标识位的,倘若发生错误,则状态位需要重置,否则无法继续正常使用。
所以,我们在第二个cin>>target前加一句:cin.clear()。
这样问题似乎就解决了。
请注意,问题才刚刚开始。
ctrl+z的输入方式也有讲究,前面说的没问题的情况,是假设你按正常次序输入了数组和结束符(例:1 空格 2 空格 3 空格 Enter Ctrl+Z Enter)。
要是输入(1 空格 2 空格 3 空格 Ctrl+Z Enter),会发生什么情况呢?你会发现之前的问题又出现了,cin>>target再次被无视!
网上关于此问题似乎有一些文章作出了解释:cin中Ctrl+Z无法结束的问题
很遗憾,它给出的现象及解释我都不认为和我遇到的问题相符。
于是我写了以下测试代码,来查看各时期cin的状态位。
这时候,正常输入数组,Enter,然后输入ctrl+z,再Enter,现象先是eof和fail被置1,然后重置状态后,一切正常。
假如ctrl+z粘连输入,就会发现eof并未被置1,仅fail=1,状态位的确被重置了,但cin就是无法继续正常使用。
这时候,我想了下,是不是ctrl+z作为非正常输入无法被解析产生fail,然后它一直停留在cin的数据缓冲区,持续产生fail?
于是我搜了下清cin缓冲区的方法,于是问题搞定了。
代码就不贴了,自己在cin.clear()后加上cin.sync()。
很让我困惑的是,假如不是我眼花的话,无论《C++ Primer》,还是《C++标准程序库自修教程与参考手册》,都完全没提及sync()清缓冲区这个重要的函数。蛋疼。
关键在于利用失败的cin>>返回0,一种触发失败的方式就是主动输入文件结束符,而Windows系统下输入文件结束符的方式,是按Ctrl + Z。
于是,实际使用中我碰到这样一个问题,请看以下代码:
#include <iostream> #include <vector> using std::cin; using std::cout; using std::endl; using std::vector; int main() { vector<int> src; cout<<"请输入整形数组:"; int temp; while (cin>>temp) { src.push_back(temp); } int target; cout<<"请输入需查找数:"; cin>>target; }
这是一个二分查找程序的一部分,意图就不多解释了,可完整运行。
但是,你会发现运行结果有些意外,第二个cin>>target似乎完全不起作用,一旦ctrl+z结束第一个循环后,程序就直接结束了。
在网上搜索一些资料或者翻翻书,我们会发现,cin是维持着一系列状态标识位的,倘若发生错误,则状态位需要重置,否则无法继续正常使用。
所以,我们在第二个cin>>target前加一句:cin.clear()。
这样问题似乎就解决了。
请注意,问题才刚刚开始。
ctrl+z的输入方式也有讲究,前面说的没问题的情况,是假设你按正常次序输入了数组和结束符(例:1 空格 2 空格 3 空格 Enter Ctrl+Z Enter)。
要是输入(1 空格 2 空格 3 空格 Ctrl+Z Enter),会发生什么情况呢?你会发现之前的问题又出现了,cin>>target再次被无视!
网上关于此问题似乎有一些文章作出了解释:cin中Ctrl+Z无法结束的问题
很遗憾,它给出的现象及解释我都不认为和我遇到的问题相符。
于是我写了以下测试代码,来查看各时期cin的状态位。
#include <iostream> #include <vector> using std::cin; using std::cout; using std::endl; using std::vector; int main() { vector<int> src; cout<<"请输入整形数组:"; int temp; while (cin>>temp) { src.push_back(temp); } cout<<"good: "<<cin.good()<<endl; cout<<"eof: "<<cin.eof()<<endl; cout<<"fail: "<<cin.fail()<<endl; cout<<"bad: "<<cin.bad()<<endl; cin.clear(); cout<<"good: "<<cin.good()<<endl; cout<<"eof: "<<cin.eof()<<endl; cout<<"fail: "<<cin.fail()<<endl; cout<<"bad: "<<cin.bad()<<endl; int target; cout<<"请输入需查找数:"; cin>>target; }
这时候,正常输入数组,Enter,然后输入ctrl+z,再Enter,现象先是eof和fail被置1,然后重置状态后,一切正常。
假如ctrl+z粘连输入,就会发现eof并未被置1,仅fail=1,状态位的确被重置了,但cin就是无法继续正常使用。
这时候,我想了下,是不是ctrl+z作为非正常输入无法被解析产生fail,然后它一直停留在cin的数据缓冲区,持续产生fail?
于是我搜了下清cin缓冲区的方法,于是问题搞定了。
代码就不贴了,自己在cin.clear()后加上cin.sync()。
很让我困惑的是,假如不是我眼花的话,无论《C++ Primer》,还是《C++标准程序库自修教程与参考手册》,都完全没提及sync()清缓冲区这个重要的函数。蛋疼。
相关文章推荐
- c++中使用std::map是遇到的小问题
- linux下rdesktop远程联接windows系统(配合xshell工具的使用及遇到的问题)
- gulp-uglify 与gulp.watch()配合使用时遇到的重复压缩问题
- 使用Pycharm 社区版配合anaconda进行代码编写遇到的一些小问题汇总
- 使用Data Access Application Block遇到的问题
- 在IIS 6 中使用HTTP压缩(Compression)遇到的一个问题
- 在nhibernate使用过程中遇到的几个问题。
- 在nhibernate使用过程中遇到的几个问题02
- 在MIDAS中使用SocketConnection遇到的问题
- 使用Oracle中fileopen命令加载文件时遇到的怪问题
- 求解在SQL中使用了where列所遇到的问题
- 遇到 Web Server 中不能使用 XmlSerializer 的问题
- 使用WebServices时候遇到“基础连接以关闭”的问题
- VC6使用过程中遇到的问题收集(1) zz
- updater application block v2.0的使用过程中遇到的问题及解决办法
- 使用Access存储Session,遇到了SessionId问题?
- 在使用BizTalk时遇到一个很郁闷的问题 之解决篇
- 使用SqlParameter参数返回值时遇到的问题
- 使用vs.net遇到的问题
- 使用System.IO.StreamReader时遇到的问题 (转)