• clear()、sync()、ignore()


    #include <iostream> 
    using namespace std; 
    int main()  
    {         
        int a;         
        cin>>a;         
        cout<<cin.rdstate()<<endl;         
        if(cin.rdstate() == ios::goodbit)   
        {   
            cout<<"输入数据的类型正确,无错误!"<<endl;               
        }         
        if(cin.rdstate() == ios_base::failbit)         
        {                 
            cout<<"输入数据类型错误,非致命错误,可清除输入缓冲区挽回!"<<endl;         
        }         
        system("pause"); 
    }  

    我们定义要输入到的变量是整型,但如果我们输入了英文字母或者汉字,那就会发生错误,cin里有个方法能检测这个错误,就是cin.rdstate(); 当cin.rdstate()返回0(即ios::goodbit)时表示无错误,可以继续输入或者操作,若返回4则发生非致命错误即ios::failbit,则不能继续输入或操作.而cin.clear则可以控制我们此时cin里对这个问题的一个标识.语发如下: cin.clear(标识符); 标识符号为:

    goodbit 无错误 
    Eofbit 已到达文件尾 
    failbit 非致命的输入/输出错误,可挽回 
    badbit 致命的输入/输出错误,无法挽回 若在输入输出类里.需要加ios::标识符号 
    通过cin.clear,我们能确认它的内部标识符,如果输入错误则能重新输入.结合真正的清空数据流方法cin.sync(),请看下例:

    #include <iostream> 
    using namespace std; 
    int main()  
    {         
        int a;         
        while(1)         
        {                 
            cin>>a;                 
            if(!cin)            //条件可改写为cin.fail()                 
            {                         
                cout<<"输入有错!请重新输入"<<endl;                         
                cin.clear();                          
                cin.sync();   //同步数据缓冲区?                
            }                 
            else                 
            {                         
                cout<<a;                         
                break;                 
            }         
        }         
        system("pause"); 
    }  

    上面的cin.clear()默认参数为0,即无错误,正常操作.当我们输入英文字母'k'时,它的状态标识改为fail,即错误,用cout对用户输出信息,再用cin.clear让错误标识改回为0,让我们可以继续输入,再清空流数据继续输入.如果我们没有了cin.clear,则会进入死循环,其过程为我们输入了英文字母,它的状态标识便为fail,当运行到条件判断时,便总是回到错误的条件表示里,并且我们再也没办法输入,因为错误的表示关闭了cin,所以会进入死循环.

    参考原文:http://www.cnblogs.com/tonglingliangyong/p/3908463.html

    关于sync()函数的作用应该是同步缓冲区的数据,而并非清除缓冲区的数据(下面补充)。清除缓冲区数据用下面这种方式。

    cin.ignore(numeric_limits<std::streamsize>::max(),'/n');//清除当前行
    cin.ignore(numeric_limits<std::streamsize>::max());     //清除cin里所有内容

    numeric_limits<std::streamsize>::max()是climits头文件定义的流使用的最大值,你也可以用一个足够大的整数代替它。

    关于sync()的例子:

    #include <iostream>
    #include <fstream>
     
    void file_abc()
    {
        std::ofstream f("test.txt");
        f << "abc
    ";
    }
     
    void file_123()
    {
        std::ofstream f("test.txt");
        f << "123
    ";
    }
     
    int main()
    {
        file_abc(); // file now contains "abc"
        std::ifstream f("test.txt");
        std::cout << "Reading from the file
    ";
        char c;
        f >> c; 
    	std::cout << c;
        file_123(); // file now contains "123"
        f >> c; 
    	std::cout << c;
        f >> c; 
    	std::cout << c << '
    ';
        f.close();
     
        file_abc(); // file now contains "abc"
        f.open("test.txt");
        std::cout << "Reading from the file, with sync()
    ";
        f >> c; 
    	std::cout << c;
        file_123(); // file now contains "123"
        //f.sync();
        f >> c; 
    	std::cout << c;
        f >> c; 
    	std::cout << c << '
    ';
    }  

    知乎见解:

      为了更好理解,以 std::ifstream f("test.txt"); 为例,对象 f 和磁盘上的文件 test.txt 就是两个相关联但不同的东西。f 有自己的缓冲区用来缓冲从 test.txt 读取的内容。而 sync() 则是强制将 test.txt 的内容「同步」到缓冲区。

    比如 test.txt 内容本来是 abc。f 被创建后缓冲区内可能就直接加载了这三个字符,今后的读写就都直接从缓冲区,而非文件本身做了。这样一来,如果此时 test.txt 的内容立即被另一个程序改成了 123,从 f 对象里读取的内容仍旧是 abc。但如果调用 sync(),则缓冲区会同步成 123。

    作者:邱昊宇
    链接:https://www.zhihu.com/question/40160488/answer/85242357
    来源:知乎

    输出(编译器g++):

    续:

    说到底其实这个函数的功能并不是用来清除缓冲区内容的,这个用途只是因为在vs系列编译器带来的副作用而已。当然给出的例子也只能在vs系列编译器上跑出正确的结果。
  • 相关阅读:
    正则表达式练习
    Linux下文件删除的原理
    (转)linux grep 正则表达式
    linux 需要记忆的知识
    linux 常用命令
    TestNG测试方法
    TestNG配置注解
    jquery 获取和设置 select下拉框的值
    Kings(状压DP)
    Tirp(状压DP)
  • 原文地址:https://www.cnblogs.com/ThatsMyTiger/p/7200308.html
Copyright © 2020-2023  润新知