Stdin和Stdout
stdin | stdout |
---|---|
标准输入文件,一般指键盘;scanf()、getchar() 等函数默认从stdin获取输入。 | 标准输出文件,一般指显示器;printf()、putchar() 等函数默认向stdout输出数据 |
下面演示用scanf()输入到stdin再由printf()输出到stdout的情况。
#include <stdio.h>
int main()
{
int a;
char ch;
do
{
printf("请输入数据:");
scanf("%d",&a); //键盘输入一个数据。
printf("%d",a); //打印输入的数据。
printf("(y/n)"); //控制循环是否继续?
scanf("%c",&ch); //y继续,n退出。
}while(ch == 'y' || ch == 'Y');
}
这个程序看似没有问题,但实际上 scanf("%c",&ch); 在读键盘输入的数据时出现了问题。
这里详细讲解一下:
程序运行后首先需要我们输入一个数据
我们输入100 然后终止符(空格或回车均可)我们发现并没有继续执行下去,我们再回车一下
我们发现并没有要求我们输入(y/n)来控制,而是程序自己终止了循环。
实际上这里的scanf("%c",&ch)已经读取到键盘输入的回车,也就是’\n’字符,我们的输入习惯是,先输入100然后终止符再输入(y/n),但是C语言库中的scanf()是从输入文件缓冲区(也就是stdin)中获取数据,我们再输入第一个数据回车的时候,缓冲区就已经缓存了’\n’字符,而正好第二个scanf()要读取的就是字符型的数据。
那么怎么避免这个情况呢。
我们在输入完数据时进行清空输入缓冲区操作fflush(stdin),就不会影scanf("%c",&ch)的读取了。(如下👇)
这里是vs2012里用fflush(stdin)清空了缓冲流,但是vs2019里用的是rewind(stdin)(如下👇)
而rewind(stdin)实质上并不是清空了stdin而是指向了缓冲流的头部,使其再次输入。
关于rewind()函数的作用和用法,后期再作补充。