输入:
scanf()
scanf()不同方式输入:
#include<stdio.h>
int main()
{
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",a+b);
scanf("%d %d",&a,&b);
printf("%d\n",a+b);
scanf("%d,%d",&a,&b);
printf("%d\n",a+b);
scanf("%d is bigger than %d", &a, &b);
printf("%d\n", a+b);
return 0;
}
输出:
只要符合代码的格式要求就能正确输出计算值。
缓冲区:
从本质上讲,我们从键盘输入的数据并没有直接交给 scanf(),而是放入了缓冲区中,直到我们按下回车键,scanf() 才到缓冲区中读取数据。如果缓冲区中的数据符合 scanf() 的要求,那么就读取结束;如果不符合要求,那么就继续等待用户输入,或者干脆读取失败。如果缓冲区中的数据不符合 scanf() 的要求,要么继续等待用户输入,要么就干脆读取失败。
第一次,正确输入:
#include <stdio.h>
int main()
{
int a = 1, b = 2, c = 3, d = 4; //修改处:给变量赋予不同的初始值
scanf("%d", &a);
scanf("%d", &b);
printf("a=%d, b=%d\n", a, b);
scanf("%d %d", &c, &d);
printf("c=%d, d=%d\n", c, d);
return 0;
}
第一次正确输出:
第二次,尝试错误输入:
当我们把最后一个值输入成a时,这并不符合变量d的正确格式,但是最后的输出结果d仍等于4,这说明最后的结果是从上一次scanf输入的缓冲区读取到的。
第三次尝试错误输入:
当我们把第三个值输入为错误格式后,程序直接终止执行,输出缓冲区的正确值。
这说明 scanf() 不会跳过不符合要求的数据,遇到不符合要求的数据会读取失败,而不是再继续等待用户输入。
总而言之,正是由于缓冲区的存在,才使得我们能够多输入一些数据,或者一次性输入所有数据,这可以认为是缓冲区的一点优势。然而,缓冲区也带来了一定的负面影响,甚至会导致很奇怪的行为,请看下面的代码:
#include <stdio.h>
int main()
{
int a = 1, b = 2;
scanf("a=%d", &a);
scanf("b=%d", &b);
printf("a=%d, b=%d\n", a, b);
return 0;
}
错误输入1:
输入两个值中间用空格隔开:
错误输入2:
输入一个值按回车:
正确输入:
按代码格式输入:a=1b=3
错误输入3:
不按代码格式输入:
中间加了一个空格就g了。
这个问题会在复习缓冲区时着重学习,下面介绍除了整数外还能输入的其他的字符格式:
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 | 读取一个字符串(以空白符为结束) |
getchar()
对于单个字符的输入,相当于简化版的scanf("%c",&c)
#include <stdio.h>
int main()
{
char c;
c=getchar();
//char c = getchar();
//putchar(c);
printf("%c",c);
return 0;
}
输出:
getche()
getche() 就比较有意思了,它没有缓冲区,输入一个字符后会立即读取,不用等待用户按下回车键,这是它和 scanf()、getchar() 的最大区别。请看下面的代码:
#include <stdio.h>
#include <conio.h>
int main()
{
char c = getche();
printf("%c",c);
return 0;
}
输出:
在我们刚输入一个字符a后紧接着后面就输出了字符a,不需要按回车,也就是不需要将字符a存入缓冲区再读取,非常的迅速。
但需要注意,getche() 位于 conio.h 头文件中,而这个头文件是 Windows 特有的,Linux 和 Mac OS 下没有包含该头文件。换句话说,getche() 并不是标准函数,默认只能在 Windows 下使用,不能在 Linux 和 Mac OS 下使用。
getch()
getch() 也没有缓冲区,输入一个字符后会立即读取,不用按下回车键,这一点和 getche() 相同。getch() 的特别之处是它没有回显,看不到输入的字符。所谓回显,就是在控制台上显示出用户输入的字符;没有回显,就不会显示用户输入的字符,就好像根本没有输入一样。
回显在大部分情况下是有必要的,它能够与用户及时交互,让用户清楚地看到自己输入的内容。但在某些特殊情况下,我们却不希望有回显,例如输入密码,有回显是非常危险的,容易被偷窥。
#include <stdio.h>
#include <conio.h>
int main()
{
char c = getch();
printf("%c",c);
return 0;
}
输出:
注意,和 getche() 一样,getch() 也位于 conio.h 头文件中,也不是标准函数,默认只能在 Windows 下使用,不能在 Linux 和 Mac OS 下使用。
对三个函数的总结
函数 | 缓冲区 | 头文件 | 回显 | 适用平台 |
---|---|---|---|---|
getchar() | 有 | stdio.h | 有 | Windows、Linux、Mac OS 等所有平台 |
getche() | 无 | conio.h | 有 | Windows |
getch() | 无 | conio.h | 无 | Windows |
gets():
输入字符串当然可以使用 scanf() 这个通用的输入函数,对应的格式控制符为%s
,上节已经讲到了;本节我们重点讲解的是 gets() 这个专用的字符串输入函数,它拥有一个 scanf() 不具备的特性。
gets() 的使用也很简单,请看下面的代码:
#include <stdio.h>
int main()
{
char a[20];
gets(a);
printf("%s",a);
return 0;
}
输出:
gets() 是有缓冲区的,每次按下回车键,就代表当前输入结束了,gets() 开始从缓冲区中读取内容,这一点和 scanf() 是一样的。gets() 和 scanf() 的主要区别是:
- scanf() 读取字符串时以空格为分隔,遇到空格就认为当前字符串结束了,所以无法读取含有空格的字符串。
- gets() 认为空格也是字符串的一部分,只有遇到回车键时才认为字符串输入结束,所以,不管输入了多少个空格,只要不按下回车键,对 gets() 来说就是一个完整的字符串。
也就是说,gets() 能读取含有空格的字符串,而 scanf() 不能。
参考文章:
C语言scanf:读取从键盘输入的数据(含输入格式汇总表) (biancheng.net)
C语言输入字符和字符串(所有函数大汇总) (biancheng.net)
输出:
在C语言中,有三个函数可以用来在显示器上输出数据,它们分别是:
- puts():只能输出字符串,并且输出结束后会自动换行。
- putchar():只能输出单个字符。
- printf():可以输出各种类型的数据。
汇总一下格式控制符:
格式控制符 | 说明 |
---|---|
%c | 输出一个单一的字符 |
%hd、%d、%ld | 以十进制、有符号的形式输出 short、int、long 类型的整数 |
%hu、%u、%lu | 以十进制、无符号的形式输出 short、int、long 类型的整数 |
%ho、%o、%lo | 以八进制、不带前缀、无符号的形式输出 short、int、long 类型的整数 |
%#ho、%#o、%#lo | 以八进制、带前缀、无符号的形式输出 short、int、long 类型的整数 |
%hx、%x、%lx %hX、%X、%lX | 以十六进制、不带前缀、无符号的形式输出 short、int、long 类型的整数。如果 x 小写,那么输出的十六进制数字也小写;如果 X 大写,那么输出的十六进制数字也大写。 |
%#hx、%#x、%#lx %#hX、%#X、%#lX | 以十六进制、带前缀、无符号的形式输出 short、int、long 类型的整数。如果 x 小写,那么输出的十六进制数字和前缀都小写;如果 X 大写,那么输出的十六进制数字和前缀都大写。 |
%f、%lf | 以十进制的形式输出 float、double 类型的小数 |
%e、%le %E、%lE | 以指数的形式输出 float、double 类型的小数。如果 e 小写,那么输出结果中的 e 也小写;如果 E 大写,那么输出结果中的 E 也大写。 |
%g、%lg %G、%lG | 以十进制和指数中较短的形式输出 float、double 类型的小数,并且小数部分的最后不会添加多余的 0。如果 g 小写,那么当以指数形式输出时 e 也小写;如果 G 大写,那么当以指数形式输出时 E 也大写。 |
%s | 输出一个字符串 |