关于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);

 

posted @ 2018-02-17 14:28  uzi2008  阅读(7740)  评论(0编辑  收藏  举报