I/O缓冲区
此帖记录缓冲区在编程中产生的各种影响及引发的相关问题 本帖最后由 风车呼呼呼 于 2022-4-12 16:28 编辑1.scanf()函数
scanf()输入结束后,将在缓冲区留下'\n',下一次向缓冲区取数据时,务必先将'\n'取出(使用getchar())
验证:
#include <stdio.h>
int main() {
int a, b;
scanf("%d", &a);
printf("a: %d\n", a);
b = getchar();
printf("b: %d\n", b);
return 0;
}
输出结果:
a
a: 7
b: 10
缓冲区留有'\n'所引发的问题:
#include <stdio.h>
int main() {
int a;
char b, c;
scanf("%d", &a);
printf("a: %d\n", a);
scanf("%c", &b);
printf("b: %c\n", b);
c = getchar();
printf("c: %c\n", c);
return 0;
}
输出结果:
5
a: 5
b:
k
c: k 本帖最后由 风车呼呼呼 于 2022-4-12 17:26 编辑
2.getchar()与while()
先上代码
#include <stdio.h>
int main() {
char i;
while((i = getchar()) != '\n'){
putchar(i);
}
putchar('\n');
return 0;
}
输出结果:
Hello World!
Hello World!
思考:根据while()的逻辑以及getchar()和putchar()的特性,为什么不是输入一个字符,界面上就紧接着打印这个字符,而是全部输出结束后才一起打印出来呢?
稍稍修改一下代码,给while换一个判断条件
#include <stdio.h>
int main() {
char i;
while((i = getchar()) != 'a'){
putchar(i);
}
putchar('\n');
return 0;
}
输出结果:
x
x
y
y
z
z
a
这下符合原先认为的逻辑了,那么开始找两者的差别
为什么判断条件设置为'\n'就不能逐一打印呢?
单独运行一条getchar语句会发现,getchar()调用结束的标志正是'\n',而while顺利循环下去的条件则是输入非换行符
那么说明,只要while不结束,甚至第一次调用的getchar语句都没有调用完
What???我在键盘上都输入了那~么一大串字符,你现在跟我讲它连第一个字符都没有读入?
没错!就是这么出乎意料,匪夷所思
下面来重新捋一捋getchar()是怎么工作的
实际上,与其说getchar()是获取用户在键盘上输入的一个字符,真实情况却是在缓冲区中获取一个字符
当缓冲区为空时,它会允许用户向缓冲区中输入数据
若缓冲区中存在数据时,它会直接取走缓冲区中的第一个字符,用户根本不需要输入
现在,返回刚才的代码讨论
我们说到在while判断条件为假之前,第一次对getchar的调用都无法结束。
第一次调用getchar()时,由于缓冲区中并没有数据,所以开始允许用户向缓冲区中输入数据
又因为一直接收不到'\n'作为函数结束标志,故在此期间用户可以一直输入(要是缓冲区满了就另说了)
假设我们输入的内容是
abc
(这便是缓冲区中的内容)
接着按下回车...
注意了!注意了!注意了!
虽然while退出的条件正是回车,但这个时候还远远没到退出循环的时候呢
这时我们对getchar()的第一次调用才刚刚准备结束
还记得getchar是要干嘛吗?没错,就是从缓冲区里取走第一个字符
所以第一次getchar()取走了'a',并且把它赋值给了变量i
紧接着进行条件判断,'a' != '\n' 成立,putchar()在屏幕上打印出字符a
然后开始第二轮循环,同理getchar()取走了'b',putchar()紧接在字符a后面打印出了字符b(putchar函数并没有自带换行,所以是挨着a后边打印)
第三轮循环,同理打印出字符c,此时屏幕上显示的正是
abc
最后第四轮循环,此时缓冲区中还留有一个'\n'
getchar()将其取出并赋值给变量i,'\n' != '\n' 关系表达式为假
不进入循环体,while循环结束
原来如此,我懂了..可是i/o缓冲区好像是最后一节课的内容诶
页:
[1]