• C++中cin对象的clear方法和sync方法的暧昧关系


    话说刚才写求最大公约数的代码时,为了提高可靠性,加入了IO错误判断,可测试结果让人不解,先看修改前的部分代码:

    int a = 0, b = 0;
    cout
    << "Please input two number to computing they GCD: ";


    while (!(cin >> a >> b))
    {
    cin.clear();
    // 将流中的所有状态值都重设为有效值
    cout << "Input Error !" << endl;
    cout
    << "Input againt: " << endl;
    }

    // gcd 即 Greatest Common Divisor,最大公约数.
    cout << "The GCD is " << gcd(a, b) << endl;

    按理(从《C++ Primer》看来的)说,输入错误时,进入了循环体,接着调用 clear 方法重设状态值,然后 cin 流对象就处于正常状态了,我们就可以重新输入两个数值以求最大公约数了。可事实是,进入循环体后,再也出不来了,一个劲儿地循环。

    我调试呀调试,发现问题可能出在 clear 方法上,可是《C++ Primer》也是这么用的呀!好吧,这是我的错,我得先检讨一下再继续往下讲。为了赶进度,我在很短的时间里把《C++ Primer》看了一遍,可这只是粗略看一遍,书上的代码基本上就没有上机实践过,我错了,原谅我吧。

    经过一番百度,发现原来是把 clear 的老情人 sync 给丢了。俗话说的好,男女搭配,干活不累。没了 sync,clear 自然就整天魂不守舍地徘徊不前,等待梦中情人的出现。好了,有请 sync 先生出场:

    while (!(cin >> a >> b))
    {
    cin.sync();     // 清除输入缓冲区中的数据流,功能与 fflush(stdin) 相同.
    cin.clear();    // 将流中的所有状态值都重设为有效值.
    cout << "Input Error !" << endl;
    cout
    << "Input againt: " << endl;
    }

     恭喜 clear 女士脱离光棍行列,终于可以让我们继续输入数值了。

    分析一下,当我们输入了错误的数值后,cin 对象处于错误状态,代码进入循环体,接着我们调用 clear 方法重设了 cin 对象的状态。此时,cin 对象已经处于正确状态了,但是有一点需要注意,这些状态只是用来告诉别人,我 cin 已经没有问题了。当然啦,神经病自己都会说自己没病,有病不是说句话就能好的,有病还得治。打从 cin 里塞进了垃圾数据之后,这些垃圾就没清除掉。所以得让 sync 把垃圾数据给清除掉,清除之后才可以再放有用的东西。OK,垃圾也清除了,状态也正常了,活可以继续干了。

    PS: 想不想知道 clear 为什么是女性?

  • 相关阅读:
    多图详解!10大高性能开发核心技术(转发)
    从 Spring Cloud 看一个微服务框架的「五脏六腑」
    eclipse中的springBoot项目 执行maven build 和maven install 报错
    Mysql怎么删除某表中的一条数据
    eclipse 中需要配置jdk、需要配置jre吗? 以及安装eclipse后需要做的一些配置
    IntelliJ IDEA 2019.2最新版本免费激活码(亲测可用)
    在springBoot项目配置项目的访问路径的时候 server.context-path不起作用的原因
    共享类型的基站概念
    oracle创建索引
    ORACLE中的DBLINK概念及使用DBLINK对远程数据库的连接
  • 原文地址:https://www.cnblogs.com/wxxweb/p/2055908.html
Copyright © 2020-2023  润新知