关于cin.sync()的解释
近几天在学cin流对象的成员函数,在看到cin.sync();时发现网上很多博客中的用法在本地的环境无法实现(VS2017)
比如如下代码:
#include<iostream> using namespace std; int main() { int a; while (1) { cin >> a; if (cin.rdstate()) //条件可改写为cin.fail() { cout << "输入有错!请重新输入" << endl; cout << cin.rdstate() << endl; cin.clear(); cin.sync();//cin.ignore(std::numeric_limits<int>::max(),'\n'); cout << cin.rdstate() << endl; } else { cout << a; break; } } system("pause"); }
运行结果如下,陷入死循环
而按网上许多人写的博客里的说法,cin.sync();应该是清空缓存区的意思
为此我换了G++来重新测试代码
得到结果是如下:
等待输入,按照G++的运行结果来看,cin.sync();又确实是清空缓冲区的功能
那么为什么在不同的编译环境下,函数的功能不一样呢?
我去查询了资料
http://www.cplusplus.com/forum/general/63860/
额,,,,学好英语是必要的
大致意思就是对于 std::cin 这些标准库「自带」的输入流来说,调用 sync() 是「实现定义」的行为
所以此处调了 sync() 以后清空、恢复原状、什么都不干都是可以的,如果没有得到预期的效果的话,可以查看自己的编译器(标准库实现)的说明文档,上面应该有写明它所使用的是哪种行为。
具体可以参考:cppreference.com
总之对这个误解的人还蛮多的,因为不少编译器里确实定义的是清空的行为(可sync明明是同步的意思啊喂,所以定义成和数据源同步的操作才会更舒服好吧)
解决方法呢,就是用cin.ignore();
cin.ignore(std::numeric_limits<int>::max(),'\n');
把第一个参数设置得足够大,这样实际上总是只有第二个参数'\n'起作用,所以这一句就是把回车(包括回车)之前的所以字符从输入缓冲(流)中清除出去,用此来达到清空数据流的操作;
这样就能吃掉一大段了,但理论上依旧不能保证吃掉一行
所以还是一次吃一个好了
cin.ignore(1,EOF);