基于C++语言的外部输入若干问题的探讨
2018-03-19尹诗玉方欢
尹诗玉 方欢
摘要:C++是一种应用非常广泛的面向对象程序设计语言,该文针对C++语言中的各种外部输入方法进行了分析探讨和举例,从C++中的cin输入流入手,主要介绍一系列输入方法并加以测试和比较。该文首先阐释了cin>>,cin.get(),cin.getline(),getline这几种输入方法的基本使用并且进行了其输入原理(即缓冲区存取)的探究,其次对该几种输入方法进行了比较,有利于今后实际应用中的区分,最后在实际输入过程中会出现的错误该文也进行了说明,给出了相关的问题处理方法。
关键词:C++外部输入;输入原理;缓冲区存取;错误处理.
中图分类号:G642.0 文献标识码:A 文章编号:1009-3044(2018)04-0080-04
Discussion on Some Problems of External Input Based on C++ Language
YIN Shi-yu,FANG Huan
(Anhui University of Science and Technology Institute of Mathematics and Big Date, Huainan 232001, China)
Abstract: C++ is an object oriented programming language that is widely used,This paper analyzes and discusses various external input methods in C++ language, starting with the CIN input stream in C++, mainly introduces a series of input methods, and tests and compares them. This paper explains cin>>, cin.get (cin.getline), (getline), the basic use of this input method and its input several principle (i.e. buffer access) inquiry, then the several access methods are compared, which helps to identify future practical application, finally in the actual input process will appear the error in this paper is also described, given relevant treatment problems.
Key words: C++ external input; input principle; buffer access; error handling
1 背景
計算机是一种信息处理机器,它的主要工作就是处理各种信息和数据。 而信息不可能都是由计算机自己生成的,因此多数实际应用的程序都需要有将用户的信息输送给计算机的功能。 同时,计算机的最终运算结果必须以某种方式呈现出来以供用户查看。一般说来,一个具有实际应用价值的程序必须具备输入输出功能[1]。C++语言作为C语言的延伸和发展,其中提供的I/O流有一个明显的优点,就是程序设计人员可以不考虑数据的类型,而直接使用cin>>a;来从键盘中提取数据,>>即为提取操作符,而C语言必须明确表示出变量的数据类型[3]。经过C++语言的学习,笔者发现书中对待不同的问题采用的外部输入方式也不相同,例如cin>>,cin.get(),cin.getline(),getline,等方法,然而书中却没有给出深入的阐释与区分。现很少有文献全面总结了C++语言中各种输入函数的用法,因此本文将从C++输入流出发,在ANSI C2.0环境下分析和研究各种输入方法适用的情况,并进行相关的对比及区分,本文所给代码均经过DEV-C++5.4.0编译通过。
2 常见的C++输入方式及其原理
C++输入即如何给程序提供数据,cin对象将标准输入表示为字节流,通常情况下,通过键盘来生成这种字符流。
流:C++的程序把输入和输出看做字节流。cin是标准输入流,输入时,程序从输入流中抽取字节;输出时,程序将字节插入输出流中,流充当了程序和流源或流目标之间的桥梁。
缓冲区:缓冲区是用作中介的内存块,它是将信息从设备传输到程序或者从程序传输到设备的临时存储工具,用以匹配程序和设备之间速率的差距[2]。
C++程序的输入输入原理如下:键盘每一次的输入结束都会把数据存入输入缓冲区,若缓冲区中存在数据内容则下一次会从缓冲区直接提取而不会由键盘输入。
2.1 cin>>的用法
[用法]由图1和图2可知cin>>是接收一个字符串,且遇“空格”,“TAB”,“回车”都结束提取过程。此外cin还有一个基本的用法即接收一个数字,用cin>>a接收,这里便不再具体用程序解读。
[原理]该操作符是根据后面变量的类型读取数据;输入结束条件为:Enter,Space,Tab键;对结束符的处理为:丢弃缓存区中的结束符。
[分析] 第一次读取字符串时遇到空格停止了,将abc读入str1,def则存入缓冲区,然后从缓冲区提取了def给了第二个字符串,这证明了cin>>丢弃了空格符,将后面字符存入缓冲区,之后直接从缓冲区中取数据。
2.2 cin.get()的使用
该输入方式有4种形式,无参,一个参数,二个参数,三个参数。无参数char ch=cin.get()等价于有1个参数cin.get(char ch);2个参数cin.get(数组名,长度),则最后一个结束符默认为Enter键;3个参数cin.get(数组名,长度,结束字符)。
2.2.1 cin.get(无参数)的用法
1) 实验程序
[用法]由上述实验可知cin.get(ch)即用来接收一个字符,且char ch=cin.get()等价于cin.get(char ch)。
2) 原理解读
[原理]1个参数时结束符默认为Enter,若要读取字符,直接cin.get()或ch=cin.get()即可;输入结束条件:Enter键;对结束符处理:不丢弃缓冲区中的结束符。
[分析一] 有程序运行结果及ASCII码值可知第一个数据取的‘a,第二个变量取的是回车,这是因为该输入方式不丢弃上次输入结束时的回车符,所以缓冲区中残留了回车符。
[分析二] 显然第一个数据取的‘a,第二个数据取的是空格(ASCII为32)。说明在输出‘a之后,直接从缓冲区调取了空格,证明没有丢弃Space字符,保存在了缓冲区。
2.2.3 cin.get(字符数组名,接受字符数目,结束字符)的用法
2 个参数cin.get(数组名,长度)等价于3个参数cin.get(数组名,长度,结束字符)中最后一个结束符默认为Enter键,这里便将两者的用法合并探究。
1) 实验程序
[用法]cin.get(字符数组名,接受字符数目,结束字符)其中结束字符可以自定义,若缺省则默认为Enter键,用来接收一行字符串,可以接收空格,但接受字符个数为长度-1,最后一个默认为‘\0。
2) 原理解读
[原理]输入结束条件:默认Enter键,可以自定义结束符;对结束符的处理:丢弃缓冲区的默认结束符Enter,自定义时不丢弃。
[分析一]第一次输入字符过长,字符串按定义的5个长度取了4个数‘1234,而‘5存入了缓冲区中,所以第二次输入字符没有从键盘读入,而是直接取了‘5,所以输出的是‘5的ASCII码值53.
[分析二] 由于结束符为‘b,故只取了之前的12,第二次输出为b,说明自定义结束符时不会丢弃缓冲区中的结束符。
2.3 cin.getline()的用法
1) 实验程序
[原理]该输入方式与cin.get(字符数组名,接受字符数目,结束字符)大致相同,但是cin.getline()当输入过长时,会出现错误,后面的cin操作将不再执行。
[分析]这里并没有读取缓冲区的‘5,而是返回了0,因为cin出错了。
2.4 getline()的用法
getline()接收一个字符串,可以接收空格,需要包含#include
1) 实验程序
[分析]getline的读取原理是将以‘\n为结束符作为一完整读取的一行,‘\n会读取。所以当之前用cin是C++ string中的,因为cin无法输入空格从而有了getline读取一行,回车作为结束,回车也读取。
3 有关的输入方式的比较
[分析]用户如果给出两个合法的数,程序会正确执行,而当给出一个不合法字符‘a时程序便不再执行cin。
4.2 cin.getline()超长导致的错误
见图17中的程序
[分析]因为getline以‘\n作为结束符,故当前面用cin读取一个字符的时候,会输入字符后点击回车,此时getline会自动读取这个回车,程序便不再请求从键盘输入。此错误可在getline之前用cin.ignore()来解决。
4.4 cin的问题处理
其实在编程过程中很多时候都会遇到诸如此类的错误,多数问题是由于cin特殊的使用原理即缓冲区存取造成的,下面笔者将简单介绍解决这些错误即清除缓冲区的几种方法。在程序中经常出现的cin.ignore(),cin.clear(),cin.fail(),cin.sync()这些函数,其实都与cin的错误处理有关。
4.4.1 cin.clear()
作用:清除cin流的错误状态,将错误标识改为默认0。
还是图17程序中cin.getline()超长出现的错误为例。解决方法便是在cin.getline()之后加上cin.clear(),则程序便读取了缓冲区的5,并输出了其ASCII码值53,解决了相关错误,由此可看出cin.clear()并没有清空缓冲区。
cin.clear()通常和cin.sync()结合使用来解决类型输入错误问题,cin.clear()默认参数为0,即无错误的正常操作。当我们输入类型错误时时,它的状态标识为fail,即错误,用cin.clear()先将错误标识改为0之后用cin.sync()清空数据流再继续输入正确的类型则能正确输出。
4.4.2 cin.sync()
作用:清除缓冲区的数据流。
由于cin在遇到空格时,就会停止输入,所以如果我在第一次输入时,利用空格隔开两个字符串,那么cin在第一次取的时候,只会读取前一个字符串,到空格结束,此时缓冲区还保留着前面输入的第二个字符串,那么第二次cin就会直接从缓冲区取残留数据,而不会请求输入。对于以上的情况解决的方案,就是在第二次调用cin>>str之前通过cin.sync()来清空输入缓冲区。
4.4.3 cin.ignore()
作用:用来清除以回车结束的输入缓冲区的内容。
cin.ignore()的作用是丢弃缓冲区的第一个字符,这在程序中也是比较常用的,程序中用cin.get()来读取字符,第一次读取时用回车结束,有上文的介紹可知,回车残留在缓冲区,会导致第二次直接从缓冲区取得回车符,而cin.ignore()则丢弃了缓冲区中的回车符,此时缓冲区是空的,故会请求从键盘输入。
在getline之前用cin进行读取的时候,由于getline以‘\n作为结束符,故当前面用cin读取一个字符的时候,会输入字符后点击回车,此时getline会自动读取这个回车,并判断结束了,用cin.ignore()将缓冲区清除后,程序便会请求从键盘输入提取,故可输出了。
5 结束语
本文通过对各种C++输入方法及其缓冲区原理的总结,更有助于以后程序设计过程中熟练的运用各种输入函数并加以区分。C++语言编程技术作为C语言编程的延伸和发展,能够更好的为计算机编程服务,更好的满足现代化发展需求。充分理解并且熟练掌握C++语言中的输入方式更是编程的基础。本文通过实例进行分析和总结,为以后的编程打下了坚实的基础。
参考文献:
[1] 姜灵敏. 缓冲机制及C++输入/输出[J]. 新课程研究:中旬刊, 2013(2):81, 84.
[2] STEPHEN PRATA.C++ Primer Plus[M]. 张海龙, 袁国忠, 译. 北京: 人民邮电出版社, 2012.
[3] 张富编. C及C++程序设计[M]. 3版. 北京: 人民邮电出版社, 2008.