zoukankan      html  css  js  c++  java
  • C++中清空缓冲区

    C++中标准输入cin有多种输入方式。。

    这篇文章罗列的还是简要易懂的。C++输入cin详解。。。如果只是简单的使用cin>>的话,会单个token的读入。但是会忽略换行符,空格,制表符等空白符。其中cin.getline()和cin.get()都会遇到一个非常棘手的事情,就是当输入的字符串,或者说缓冲区中的字符多于第二个参数int的要求时。缓冲区中残余的字符串怎么处理

          1. cin>>

            cin>> var,只会忽略空白符,按照参数var的格式,读入一个合法的字符串。剩下的字符就残留在缓冲区中,不会影响任何状态。下一次就接着上一次读取的位置开始读取缓冲区。

            对于代码

            int n;
            cin >> n;

            很可能发生的情况是,用户输入的是单词,不是数字。对于这种类型不匹配的情况,将采取如下措施:

            • n的值不发生变化
            • 不匹配的输入将留在输入队列(缓冲区)中
            • cin对象中的一个错误标记被设置
            • 对cin方法的调用将返回false。(对于需要被转换为bool的类型)

            随后,无法再调用cin进行输入。程序员应采取下述3个措施进行错误处理:

            1. 重置cin以接收新的输入
            2. 删除错误输入
            3. 提示用户输入

            1和2的步骤不能调换。因为步骤二要求cin能正常工作。

            给出下面处理输入不合法的例子:

            int n;
            while(!(cin >> n)) {
            cin.clear(); //reset input
            while(cin.get() != ' ')
                continue;
              cout << "Please enter a number: ";
            }

            注意当输入错误时,n的值是保持不变的。cin >> n返回false。。

          2. cin.getline(char*, int[, char])

            cin.getline()遇到' '会将' '从缓冲区中取出。如果缓冲区中的字符串长度超过int。那么字符串会残留在缓冲区中,但是这时cin的状态会被设置为错误。直接关闭输入。所以如果不做出cin的错误处理,在这个cin作用域以后调用cin时,不会执行这条调用语句。只会直接返回一个任意负值,表示错误。

          3. cin.gets()

            cin.getline()遇到' ',直接返回,' '留在缓冲区中。如果缓冲区中的字符串长度超过int,那么多出的字符串会残留在缓冲区中,且cin的状态不会改变。下一次使用cin时,正常从缓冲区中读取字符。

    根据以上特点,会遇到一些细小错误。

    int a;
    char word[5];
    cout << "Enter a number: "; cin
    >> a;
    cout << "Enter a word: "; cin.getline(word,
    5); cout << "a is :" << a << endl; cout << "word is:" << word << endl;

    上述语句会出现下面的错误:

              1. Enter a number: 1234[ENTER]
                
                Enter a word: a is :1234
                
                word is:

                原因就在于cin >&gt a;执行时,读入缓冲区中的1234,留下' '(Enter键产生的)。cin.getline(word, 5)碰到残留的' '。返回,所以读进word的是个空字符串。解决办法就是:

                (cin >> a).get() //(用cin.get()来消除缓冲区中残留的‘
                ’
                
              2. char word1[20];
                char word2[20];
                cin.get(word1, 20);
                cin.get(word2, 20);

                这种清空,word2将读进空字符。。因为cin.get(word1, 20);将' '留在缓冲区中。下一次cin.get(word2, 20);一开始就碰到了' '.直接返回。无论后面调用多少次cin.get(char *,...)都无法跳出这个' '。还是要使用cin.get(void)消除残留的' '。。

                cin.get(word1, 20).get();
                
              3. 对于输入字符串长于设置的最大长度时。对于cin.getline(char *,...)要进行错误处理。对于cin.get(char *,...)不用进行错误处理。由于缓冲区残留着字符串,两者都会造成后续cin处理输入有非常大的不确定性。最好的办法是在使用cin.getline(char *,...)和cin.get(char *,..)后将缓冲区设置为空。具体处理办法,这篇文章提供了几种差异很大的C语言清空缓冲区的方法:C语言清空输入缓冲区的N种方法。。C++对决大多数方法均兼容。只需稍作改变。。其中我很喜欢那个最经典的C方式。C++中可以这样做:

                while(cin.get() != '
                ') ;

    在C++中,对于字符串的管理,可以直接使用C++库的string类。非常简单掌握。在性能上也没有过多的消耗。

    如果涉及到C风格的字符数组存储字符串,那么在输入时,建议使用cin.get()。一方面,老式编译器不支持cin.getline()。另一方面,cin.get()对输入的管理更仔细。赋予程序员更多的管理选择。。技术要求也不高。。

  • 相关阅读:
    台州 OJ 3847 Mowing the Lawn 线性DP 单调队列
    洛谷 OJ P1417 烹调方案 01背包
    快速幂取模
    台州 OJ 2649 More is better 并查集
    UVa 1640
    UVa 11971
    UVa 10900
    UVa 11346
    UVa 10288
    UVa 1639
  • 原文地址:https://www.cnblogs.com/xyqhello/p/3521495.html
Copyright © 2011-2022 走看看