cin的错误标记和缓冲区清空

来源:互联网 发布:电子琴教学软件 编辑:程序博客网 时间:2024/05/16 19:21


先看下面的代码:

[html] view plaincopyprint?
  1. vector<int> intVtr;  
  2. intVtr.insert(intVtr.end(), istream_iterator<int>(cin), istream_iterator<int>());  

上面的代码就是从标准输入中得到int型数字,并把值插入到intVtr中。当遇到非数字字符时,输入结束。

问题是,现在我要继续从标准输入读进int数字并插入intVtr结尾(也可以在其他位置,本文假定在结尾),那么该怎么写代码?开始的时候我习惯性的继续写:

[cpp] view plaincopyprint?
  1. //使用过intVtr之后  
  2. copy(istream_iterator<int>(cin), istream_iterator<int>(), inserter(intVtr, intVtr.end()));  

编译运行时发现,这个copy根本不起作用,没有机会在标准输入中输入数字,这是为什么?搜索一下istream_iterator吧:在www.cplusplus.com里发现这么句话:

A special value for this iterator exists: the end-of-stream; When an iterator is set to this value has either reached the end of the stream (operator void* applied to the stream returns false) or has been constructed using its default constructor (without associating it with any basic_istream object).

这就发现问题所在了:标准输入的结尾标记是istream_iterator<int>(),即the end-of-stream;end-of-stream又被标记成一个非致命的输入错误,所以,后面的标准输入不能进行下去,必须这样写:

[html] view plaincopyprint?
  1. //使用过intVtr之后  
  2. cin.clear(); //清除错误标记  
  3. cin.sync(); //清空缓冲区  
  4. copy(istream_iterator<int>(cin), istream_iterator<int>(), inserter(intVtr, intVtr.end()));  

这样就能继续了:)

如果只调用cin.clear(),错误标记是被删除了,可以继续标准输入了。但是别忘了,上次输入的非数字字符(就是这个字符标记了end-of-stream)还在缓冲区里呆着呢,继续cin的话,会立即得到这个非数字字符,导致又一个end-of-stream,于是copy立即返回,结果什么也没得到。

如果只调用cin.sync(),缓冲区是被清空了,但是错误标记还在,依然没法继续输入。

所以cin.clear()和cin.sync()一个都不能少,但是顺序可以颠倒。

另1:cin.ignore()函数也能替代cin.sync()?待继续研究。

另2:copy也可写为(纯属为了熟悉STL才故意这么写):

[html] view plaincopyprint?
  1. copy(istream_iterator<int>(cin), istream_iterator<int>(), back_inserter(intVtr));  
0 0
原创粉丝点击