深入理解C/C++标准输入输出,cin、scanf、getchar()、文件结束符EOF等常见问题详解

问题1:为什么我用while(cin>>a)一直跳不出循环?(cin的">>"函数返回值是什么?)

问题描述:《C++ primer》上也出现过类似如下代码,然后自己在控制台输入数据,一直输入都跳不出循环。

1
2
3
int a;
while(cin>>a){
}

原因:cin是一个类,没有返回值,while判断条件其实是在判断">>“函数的返回值。”>>“是一个被重载过的运算符,这个重载函数的返回值类型为istream&,返回值通常就是输入流cin本身,如果没有遇到错误输入或者文件末尾(EOF),cin就一直有效,当然就跳不出while循环。当你在键盘上输入Ctrl+Z,再按Enter键,就等同于输入遇到了文件末尾EOF,遇到EOF后,”>>"函数的返回值是0,就能结束while循环了。

.
.

问题2:scanf的返回值是什么?(EOF是什么类型的数据,值是多少?)

问题:while(scanf("%d %d",&a,&b)){ }为何是死循环?遇到文件结束符EOF也跳不出循环?
原因:scanf是函数,这和cin不同,cin是一个类,而">>“是cin类中的函数。scanf返回的是成功输入数据的个数,例如scanf(”%d %d",&a,&b)成功输入两个数,返回值就是2,scanf("%d",&a)成功输入一个数,返回值就是1。当遇到文件末尾时,scanf函数返回值是EOF。
EOF是一个宏,标准规定EOF必须是一个int类型的负数,编译器通常令EOF的值为-1。因此,想要跳出循环,要写成while( scanf("%d %d",&a,&b) !=EOF){ }。

.
.

问题3:为什么我cin只输入1个或几个数,在键盘上输入了多个(超过几个)数之后,控制台输入界面仍然不停止?(输入的数据什么时候才会进入缓冲区?)

问题描述:例如以下代码,明明只用cin输入2个数,在键盘上输入数据空格重复多次仍要继续输入。
输入示例:1空格2空格3空格4空格5回车

1
2
int a,b;
cin>>a>>b;

原因:调用cin的">>“函数时,程序就等着用户按键,直到用户按下回车键,包换换行符在内的这一行数据才被放入缓冲区中,形成输入流,提取符”>>"才能从中提取数据。也就是说,没按下回车键之前,你在键盘上输入的数据都还没被放入缓冲区只是在控制台上显示出你按下的数据了而已,这也是为什么我们输错了的时候还能按退格键删除数据然后重新输入。
以上面程序为例,当你在键盘上输入了超过2个字符时,其他字符也会被保留在缓冲区中,等待后面程序中的cin>>读取,若后面程序中再出现cin>>c之类的,程序也不会出现控制台等待用户输入,而是直接读取缓冲区中剩下的数据,直到缓冲区中的字符读完后,才等待用户按键。

.
.

问题4:使用getchar()函数,我明明输入的是数字1,怎么输入的是49?(getchar()函数的返回值是什么?)

:getchar()函数会从stdin中读入一个字符(空格回车等空白符它也不会跳过,通通都读),并返回一个int型数据,返回的是输入字符的ASCII码。也就是说,你输入数字1,它返回的是数字1的ASCII码49,你输入字符A,它返回的是字符A的ASCII码65,你输入空格,它返回的是空格的ASCII码32。hehehe,一般都是用getchar()来判断是否已经到了一行末尾,因为它换行符也读。
以下为getchar()函数实测
在这里插入图片描述
我在键盘输入的是:3空格AB空格7空格1空格2回车,可以看到scanf输入的3输出也是3,getchar把空格也读进来了,并且输出空格的ASCII码32。

在这里插入图片描述

五:在大多数场合,用scanf和printf是真的比cin和cout快,亲测。
但是scanf和printf用着麻烦啊,每次还要自己写输入输出类型%c%f%d什么的,而cin和cout的">>"、"<<"都是被重载过的运算符,可以读入或输出各种类型的数据,用着真是爽。

这就是“深入理解C/C++标准输入输出”???我.厚颜无耻.真,只是为了写个像那么回事的题目。以上都是我的粗浅理解,若有误,望批评指正。