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() != '\n')
              continue;
            cout << "Please enter a number: ";
          }

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

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

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

        3. cin.gets()

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

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

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

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

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

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

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

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

              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() != '\n') ;

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

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

C++中清空缓冲区的更多相关文章

  1. C++编程中对缓冲区的理解(OS默认4096大小的缓冲区,有例子,很形象)

    什么是缓冲区缓冲区又称为缓存,它是内存空间的一部分.也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区.缓冲区根据其对应的是输入设备还是输出 ...

  2. C语言:清空缓冲区

    缓冲区的优点很明显,它加快了程序的运行速度,减少了硬件的读写次数,让整个计算机变得流畅起来:但是,缓冲区也带来了一些负面影响,经过前面几节的学习相信读者也见识到了.那么,该如何消除这些负面影响呢?思路 ...

  3. gcc c语言中scanf输入格式不正确,清空缓冲区问题

    我的博客:www.while0.com 折磨了一下午,只因为fflush(stdin)再gcc里和vc里表现不一致.gcc里不能够清空缓冲区.直接上例子: #include <stdio.h&g ...

  4. [java,2017-05-16] java中清空StringBuffer的方法以及耗费时间比较

    java中清空StringBuffer的方法,我能想到的有4种: 1. buffer.setLength(0);  设置长度为0 2. buffer.delete(0, buffer.length() ...

  5. Java NIO中的缓冲区Buffer(一)缓冲区基础

    什么是缓冲区(Buffer) 定义 简单地说就是一块存储区域,哈哈哈,可能太简单了,或者可以换种说法,从代码的角度来讲(可以查看JDK中Buffer.ByteBuffer.DoubleBuffer等的 ...

  6. 转:Sql Server中清空所有数据表中的记录

    如果要删除数据表中所有数据只要遍历一下数据库再删除就可以了,清除所有数据我们可以使用搜索出所有表名,构造为一条SQL语句进行清除了,这里我一一给各位同学介绍.   使用sql删除数据库中所有表是不难的 ...

  7. 【转】Linux 中清空或删除大文件内容的五种方法(truncate 命令清空文件)

    原文: http://www.jb51.net/article/100462.htm truncate -s 0 access.log -------------------------------- ...

  8. scanf_s获取参数,清空缓冲区,判断是否读取成功

    #include<stdio.h> int main() { ]; ) { printf("Please input:\n"); ); ) { printf(" ...

  9. Sql Server中清空所有数据表中的记录

    Sql Server中清空所有数据表中的记录 清空所有数据表中的记录: 代码如下:exec sp_msforeachtable  @Command1 ='truncate table ?'删除所有数据 ...

随机推荐

  1. ArcGIS API for JS4.7加载FeatureLayer,点击弹出信息并高亮显示

    我加载的是ArcGIS Server本地发布的FeatureService,ArcGIS API for JS4.7记载FeatureLayer时,在二维需要通过代码启用WebGL渲染,在三维模式下, ...

  2. HTML5新特性postMessage解决跨域

    window.postMessage的功能是允许程序员跨域在两个窗口/frames间发送数据信息.基本上,它就像是跨域的AJAX,但不是浏览器跟服务器之间交互,而是在两个客户端之间通信.让我们来看一下 ...

  3. DOM操作XML文件

    一.IE中的XML(IE低版本才支持) 在统一的正式规范出来以前,浏览器对于 XML 的解决方案各不相同.DOM2 级提出了动态创建 XML DOM 规范,DOM3 进一步增强了 XML DOM. 所 ...

  4. CSP vs Actor Go vs Erlang

    源于从Erlang到Go的一些思维碰撞,就像当初从C++到Erlang一样,整理下来记于此. Actor Actor模型,又叫参与者模型,其”一切皆参与者(actor)”的理念与面向对象编程的“一切皆 ...

  5. Redis系列一:reids的单机版安装

    环境:VM+centos6+xshell 1.准备好linux的虚拟机,这里用的是centos6,具体方法百度 2.进入software目录,创建一个redis的目录来存放下载的redis包 cd s ...

  6. 【洛谷】【单调栈】P4333 [COI2007] Patrik

    --接上一篇题解,[洛谷][单调栈]P1823音乐会的等待 关于题目大意在上一篇题解里已经说清楚了,这里不再多阐述 想看题目->戳这里 [算法分析:] 在对元素a进行判断时,如果它与栈顶元素相等 ...

  7. 20155207王雪纯《网络对抗》Exp4 恶意代码分析

    20155207 <网络对抗> 恶意代码分析 学习总结 实践目标 1.是监控你自己系统的运行状态,看有没有可疑的程序在运行. 2.是分析一个恶意软件,就分析Exp2或Exp3中生成后门软件 ...

  8. controlfile作为RMAN的repository时,对 keep time 的测试

    4月2日,首先查看系统状况: SQL> show parameter control NAME                                 TYPE        VALUE ...

  9. python变量名感悟

    我感悟的是python的变量名其实就可以理解为C/C++中的指针! 1.python的变量在使用之前必须赋值,就像指针在使用之前不能为空. 2.python的内存可以用del释放,C++可以用dele ...

  10. 带阴影的圆形 QLabel

    带阴影的圆形 Label 来自: 公孙二狗