C语言编程中,输入输出是基本操作,printf和scanf并不是C语言中的唯一的输入输出选择,对于输入有scanf()、getchar()、getche()、getch()、gets();对于输出有printf()、puts()、putchar(),他们各有自己的使用场景,本篇文章主要介绍常用的scanf和printf
一:scanf详解
scanf 是 scan format 的缩写,意思是格式化扫描,也就是从键盘获得用户输入
1,格式化输入
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
//输入一个整数
int a;
scanf("%d",&a);
printf("a = %d\n",a);
getchar();
//输入一个字符
char b;
scanf("%c",&b);
printf("b = %c\n",b);
getchar();
//输入一个字符串
char c[10] = {0};
scanf("%s",c);
printf("c = %s\n",c);
}
运行结果:
上面的举例是scanf的基本用法,看到上面的例子有同学就有疑问了为什么两次输入之间要有getchar(),这个后面会讲到。对于scanf输入有严格的格式控制符,如下
格式控制符 | 说明 |
---|---|
%c | 读取一个单一的字符 |
%hd、%d、%ld | 读取一个十进制整数,并分别赋值给 short、int、long 类型 |
%ho、%o、%lo | 读取一个八进制整数(可带前缀也可不带),并分别赋值给 short、int、long 类型 |
%hx、%x、%lx | 读取一个十六进制整数(可带前缀也可不带),并分别赋值给 short、int、long 类型 |
%hu、%u、%lu | 读取一个无符号整数,并分别赋值给 unsigned short、unsigned int、unsigned long 类型 |
%f、%lf | 读取一个十进制形式的小数,并分别赋值给 float、double 类型 |
%e、%le | 读取一个指数形式的小数,并分别赋值给 float、double 类型 |
%g、%lg | 既可以读取一个十进制形式的小数,也可以读取一个指数形式的小数,并分别赋值给 float、double 类型 |
%s | 读取一个字符串(以空白符为结束) |
2,带空格输入到多个变量
#include <stdio.h>
#include <stdlib.h>
int main()
{
//输入一个整数
int a, b, c;
scanf("%d %d", &a, &b);
printf("a=%d, b=%d\n", a,b);
scanf("%d %d", &a, &b);
printf("a=%d, b=%d\n", a,b);
scanf("%d, %d, %d", &a, &b, &c);
printf("a=%d, b=%d, c=%d\n", a,b,c);
scanf("%d not equal %d", &a, &b);
printf("a=%d, b=%d\n", a,b);
}
运行结果:
第一个 scanf() 的格式控制字符串为"%d %d"
,中间有一个空格,而我们却输入了1 2
,中间有多个空格。第二个 scanf() 的格式控制字符串为"%d %d"
,中间有多个空格,而我们却输入了1 2,中间只有一个空格。这说明 scanf() 对输入数据之间的空格的处理比较宽松,并不要求空格数严格对应,多几个少几个无所谓,只要有空格就行。
用户每次按下回车键,程序就会认为完成了一次输入操作,scanf() 开始读取用户输入的内容,并根据格式控制字符串从中提取有效数据,只要用户输入的内容和格式控制字符串匹配,就能够正确提取。
本质上讲,用户输入的内容都是字符串,scanf() 完成的是从字符串中提取有效数据的过程
3,连续输入到数组
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a[5];
int i = 0;
for(i=0; i<5; i++)
{
scanf("%d",a+i);
}
for(i=0; i<5; i++)
{
printf("%d ",a[i]);
}
printf("\n");
}
运行结果:
4,带空格的字符串输入
#include <stdio.h>
#include <stdlib.h>
int main()
{
char str[100];
scanf("%[^\n]",str);//以换行符作为字符串输入的结束
printf("%s\n",str);
}
运行结果:
利用格式符"%[^]",可以输入带空格的字符串到数组。需要注意的是方括号里边的^后面的字符表示的是输入的结束符,如同默认情况下空格和回车键以及TAB键是作为字符串输入的结束符一样,利用此格式符便相当于由编程者自己指定一个输入结束符。
5,刷题常用的对同一变量连续输入
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a;
while(scanf("%d",&a)!=EOF)
{
printf("a = %d\n",a);
}
}
EOF在scanf连用时代表-1的意思,当用到while(scanf()!=EOF),代表的意思是一直输入,直到scanf返回的值是-1时才会停止输入,也可以在while里面加上一些约束条件,使输入在特定的条件下就会停止,也可以在输入完成后按下Ctrl+z,可以强行停止输入
6,scanf输入的本质
从本质上讲,我们从键盘输入的数据并没有直接交给 scanf(),而是放入了缓冲区中,直到我们按下回车键,scanf() 才到缓冲区中读取数据。如果缓冲区中的数据符合 scanf() 的要求,那么就读取结束;如果不符合要求,那么就继续等待用户输入,或者干脆读取失败。
需要注意的是如果缓冲区中的数据不符合 scanf() 的要求,要么继续等待用户输入,要么就干脆读取失败。
问题回到了1章节,为什么要在每个输入后面加个getchar(),如果不加运行结果如下:
出现这种现象就是和缓冲区有关,当我们按下enter键的时候,缓冲区里是有enter的控制符,会当做第二次scanf的输入,所以需要用getchar去清除缓冲区里的enter控制符。