目录
一、scanf函数
1.函数原型
2.返回值
3.常见的格式说明符
二、getchar()函数
函数原型
三、缓冲区
行缓冲
scanf()的特性
清空输入缓冲区
使用getchar()清空缓冲区
使用scanf()清空缓冲区
其他方式
fllush(stdin)
本文只是对scanf函数、getchar函数简单的说明,以及对缓冲区简单的介绍
一、scanf函数
1.函数原型
int scanf( const char *format [,argument]... );
scanf函数是C语言中一个标准输入函数,被声明在头文件stdio.h中。
一般形式为:
scanf("格式控制字符串",地址表列);
将键盘上输入的数据,按照用户指定的格式,存储到相应的变量之中。
2.返回值
函数返回值为int型。scanf函数成功读入数据则会返回读入数据的项数,返回值为 0 表示未分配任何字段。尝试读取字符时遇到文档末尾字符或字符串末尾字符,则返回值为 EOF。
例子:
#include<stdio.h> int main() { int ret = 0; int a = 0; int b = 0; ret = scanf("%d,%d", &a, &b); printf("%d", ret); return 0; }
运行结果:
scanf函数成功读入数据时,会返回读入数据的项数。
只有第一项读取成功时,则会返回1;当第一项读取失败时,则返回0。
如果遇到错误或遇到结束标志,返回值为EOF(EOF就是end of file,值为-1)。
end of file这个操作可以敲击Ctrl+z 或者Ctrl+d(vs中需要敲击Ctrl+z三次)。
知道这一点,那么就可以写一个循环来实现多组输入输出:
#include<stdio.h> int main() { int a = 0; int b = 0; while (scanf("%d", &a) != EOF) { printf("a=%d ", a); } return 0; }
3.常见的格式说明符
数据类型 | 格式说明符 |
int | %d |
long | %ld |
float | %f |
double | %lf |
char | %c |
字符串(char类型数组) | %s |
二、getchar()函数
函数原型
getchar()标准C库函数,用来读取单个字符的函数。
int getchar( void );
返回值为int型,参数为void。
getchar返回的是字符的ASCII码值,所以是int型;在getchar()读取结束或者失败时,会返回EOF。
例子:
int main() { int ch = getchar(); putchar(ch); return 0; }
putchar()是标准C库函数,用来输出字符。
这里可以看出getchar只会读取一个字符。
while循环连续读取单个字符
#include<stdio.h> int main() { int ch = 0; while ((ch = getchar()) != EOF) { putchar(ch); } if(ch==EOF) { printf("%d",ch); } return 0; }
运行结果:
三、缓冲区
缓冲区(Buffer)又称为缓存(Cache),是内存空间的一部分。计算机在内存中预留了一定的存储空间,用来暂时存储输入或输出的数据,这部分预留的空间就叫做缓冲区(缓存)。
我们输入一串字符串时,当我们按下回车键时,才会进行打印,如果我们不按下回车键,就可以一直输入,这种就是缓冲输入。但是当我们按下任意键,则会立即有响应,这种就是无缓冲输入。
根据缓冲区的输入输出设备可以分为输入缓冲区和输出缓存区。
根据数据刷新的时机可以分为:全缓冲、行缓冲和不带缓冲。这里只简单的说明行缓冲。
行缓冲
当在输入和输出中遇到换行符时,才会执行真正的输入输出操作。行缓冲的典型代表就是键盘输入数据。
scanf()的特性
当遇到scanf函数时,程序会先检查输入缓冲区中是否存在数据:
如果没有数据,就等待用户输入。用户从键盘输入的每个字符都会暂存在缓冲区中,直到用户按下回车键,产生换行符
,输入结束,scanf()才会从缓冲区中读取数据,并赋值给变量。如果有数据,那就看数据是否符合格式字符串的规则。
scanf函数会忽略一些空白字符,例如空格、换行符、制表符等。
一些简单的例子
#include<stdio.h> int main() { int a = 0; int b = 0; int c = 0; scanf("%d", &a); scanf("%d", &b); scanf("%d", &c); printf("a=%d,b=%d,c=%d ", a, b, c); return 0; }
运行结果:
可以看出scanf在进行读取时忽略了空格和
,缓冲区就只有空格和
。
那为什么会说scanf忽略了换行符
呢
#include<stdio.h> int main() { int a = 0; int b = 0; int c = 0; scanf("%d", &a); b = getchar(); printf("%d ", b); printf("%d ", a); return 0; }运行结果:
可以看到这里的getchar()读取了ASCII码为10的字符,也就是换行符
,也就是说明scanf函数不会读取换行符
。
从这两个代码中不难看出,从键盘中输入的数据会暂存在输入缓冲区中,函数再去读取这些数据,程序结束后,释放缓冲区。
清空输入缓冲区
使用getchar()清空缓冲区
int c; while((c = getchar()) != ' ' && c != EOF);
使用scanf()清空缓冲区
scanf("%*[^ ]"); scanf("%*c");
%*[^
]:匹配处理
以外的所有字符,不赋值给变量。
%*c:的意思是匹配一个字符(%c 是匹配字符),但不把它赋值给变量。
第一个scanf()会从缓冲区中读取
以外的字符,不赋值给变量,也就相当于丢弃,此时缓冲区中只有一个
,而第二个scanf()就是将这个
读取并丢弃。
其他方式
fllush(stdin)
根据C 标准,使用 fflush(stdin) 是未定义的行为,这种用法只在部分编译器上有作用,通用性差,不建议使用。