一、格式输入、输出函数
计算机向外部设备(如显示器、打印机、磁盘等)输出数据称为“输出”。
从外部设备(如键盘、鼠标、扫描仪、光盘、磁盘)向计算机输入数据称为“输入”。
输入与输出是以计算机主机为主体而言。
C语言本身不提供输入/输出语句,输入/输出操作由函数实现。
在C标准函数库中提供了一些输入/输出函数。
如printf()函数,格式输出;scanf()函数,格式输入;putchar()函数,字符输出;getchar()函数,字符输入。
二、格式输出函数printf()
printf()函数包含在stdio.h文件中,因此在程序的开头需要将其包含进来。
1.功能
按照用户指定的格式,向系统的输出设备,如屏幕输出若干个任意类型数据。
2.格式
printf("格式控制字符串",输出列表);
例
printf("请输入账号:\n");printf("%d,%c",i,str);
3.说明
“格式控制字符串”是用双引号括起来的字符串。
也称“转换控制字符串”,它指定输出数据项的类型和格式。
它包括格式说明、普通字符、转义字符。
1)格式说明字符串:
格式说明符由“%”和格式字符串组成,它的作用是将输出的数据项转换为指定的格式输出。
例如:
%d:按十进制整型输出;
%ld:按十进制长整型输出;(小写的L)
%c:按字符型输出;
%f:按单精度型输出;
%7.2f:按单精度型输出,输出宽度为7,保留两位小数。
%5d:按十进制整型输出,宽度为5,数据不足宽度时,左补空格,即右对齐。
%-5d:按十进制整型输出,宽度为5,数据不足宽度时,右补空格,即左对齐。
2)格式字符串的一般形式如下:
[标志][输出最小宽度][.精度]类型
其中:
方括号[]中的项为可选项。
标志:表示标志字符。
有-+#空格4种。
其中最常用的为“-”左对齐,长度不足时,右补空格。默认是右对齐,左补空格。
输出最小宽度:用十进制整数来表示输出的最少位数。
若实际数多于定义的宽度,则按实际位数输出,若实际位数少于定义的宽度则补以空格或0。
精度:精度格式符以“.”开头,后跟十进制整数。
本项的意义是如果输出数字,则表示小数的位数。
如果输出的是字符,则表示输出字符的个数。
若实际位数大于所定义的精度数,则截去超过的部分。
类型:类型字符也称格式说明符,用以表示输出数据的类型。
由“%”和格式字符串组成,其格式字符和附加格式说明字符。
3)printf()函数常用格式字符
格式字符 | 说明 |
d | 以带符号的十进制形式输出整数(正数不输出符号) |
o | 以八进制无符号形式输出整数(不输出前导符0) |
x,X | 以十六进制无符号形式输出整数(不输出前导符0x或0X) |
u | 以无符号十进制形式输出整数 |
c | 以字符形式输出,只输出一个字符。 |
s | 以字符串形式输出 |
f | 以小数形式输出单、双精度数,隐含输出6位小数。 |
e,E | 以标准形式输出单、双精度数,数字部分小数位数位6位。 |
g,G | 选用%f或%e格式中输出宽度较短的一种格式,不输出无意义的0。 |
总之,就是输出时的那个“%d”这样的代替品。
例:
#includevoid main() { printf("%x,%o,%d,%c", 10, 15, 60, 66);}
分析:
就是把十进制数,进行%x十六进制转换输出;%o八进制转换输出;%d十进制转换输出;%c字符的形式转换输出。
运行结果:
printf()函数附加格式说明
附加格式说明符 | 说明 |
小写字母l | 用于长整型,可加载格式符d、o、x、u前面 |
m(代表一个正整数) | 数据最小宽度 |
n(代表一个正整数) | 对实数,表示输出n位小数; 对字符串,表示截取的字符个数。 |
-(减号) | 输出的数字或字符在域内左对齐。 |
4)普通字符。
即需要原样输出的字符。
如例子中的文字、逗号,在显示中起提示作用。
5)转义字符。
转义字符是C语言中表示字符的一种特殊形式。
通常使用转义字符表示ASCII码字符集中不可打印的控制字符和特定功能的字符。
如用于表示字符常量的单引号,用于表示字符串常量的双引号和反斜杠等。
转义字符用反斜杠\后面跟一个字符或一个八进制或十六进制数表示。
常见的转义字符有:
转义字符 | 意义 |
\n | 回车换行 |
\t | 水平制表 |
\v | 垂直制表 |
\r | 回车 |
\b | 退格 |
\a | 响铃 |
\f | 换页 |
\\ | 反斜杠。(因为一个反斜杠代表转义,所以需要再加一个。) |
\? | 问号字符 |
\' | 单引号字符 |
\" | 双引号字符 |
\0 | 空字符(NULL) |
\ddd | 任意字符 |
\xhh | 任意字符 |
字符常量中使用单引号和反斜杠,以及字符串常量中使用双引号和反斜杠时,都必须使用转义字符表示,即在这些字符前加上反斜杠。
例如:
用字符串输出:你好“坏”啊!
#includevoid main() { printf("你好“坏”啊!\n"); printf("你好\"坏\"啊!");}
分析:
因为用中文的双引号的话,会因为跟英文的双引号不冲突,所以不会出错。
但如果使用英文的双引号时,会跟包围的双引号发生冲突,所以就需要用反斜杠来进行转义。
而\n则表示换行,让其以两行的形式输出。
运行结果:
在C程序中使用转义字符\ddd或者\xhh可以方便灵活地表示任意字符。
\ddd为反斜杠后面跟3位八进制数的值,即为对应的八进制ASCII码值。
\x后面跟两位十六进制数,该两位十六进制数位对应字符的十六进制ASCII码值。
6)“输出列表”是需要输出的一些数据项,可以是表达式。
例如:假如变量a=3,b=4,那么printf("a=%d, b=%d", a, b);输出a=3,b=4。
其中两个%d是格式说明,表示输出两个整数,分别对应变量a和b。
“a=”、“b=”是普通字符,原样输出。
输出表列中给出了各个输出项,要求格式字符串和各输出项在数量和类型上应该一一对应。
4.注意事项
使用printf()函数应注意如下几点。
1)除了X、E、G外,其他格式字符必须用小写字母。
如%d不能写成%D。
2)可以在“格式控制”字符串包含转义字符。
如\n、\t等。
3)格式符以%开头,以上述9个格式字符结束,中间可以插入附加格式字符。
4)如果想输出字符%,则应当在“格式控制”字符串中用两个%表示。
如输出“30%”的输出方式:
printf("30%%");
A例:
整型数据格式输出
#includevoid main() { int a = 3, b = 5; printf("%d,%d\n", a, b); printf("a=%d,b=%d\n", a, b); printf("a=%3d,b=%3d\n", a, b); printf("a=%-3d,b=%-3d\n", a, b);}
分析:
第4行输出:
单纯的输出变量a和b的数。
第5行输出:
输出带“普通字符”和变量a和b的数。
第6行输出:
可以理解成分配了3个位的数。
因为a和b都只占1位,所以剩下的两位就用空格代替。
因为是正数,所以右对齐。
第7行输出:
也可以理解成分配了3个位的数。
因为是负数,所以是左对齐。
运行结果:
B例:
实型数据输出(也就是小数)
#includevoid main() { float a = 135.789; double b = 123321.456654123; printf("a=%f,%.4f,%.4lf,%8.2f\n", a, a, a, a); printf("b=%f,%lf,%.4f,%8.2f\n", b, b, b, b); }
分析:
首先定义了一个float类型变量a,和double类型变量b。
然后是按照精度和位数进行格式化输出。
从下面的结果可以看出,单精度的最大数位是6位。
即小数点后面只会显示6位,多了就舍去了。
然后是.4f,也就是小数点后面保留4位。
而.4lf跟.4f的结果是一样的,也就是字母小写的“l”,对单精度类型的数据没有任何作用。
再然后是8.2f:
首先是8,表示先分配8个位数(宽度),包括小数点和后面的小数。
如果赋予的数,超过了这个位数,就原样输出整数部分。
至于小数部分,就要看%8.2f的.2所代表的精度。
总之,先将赋予的数,进行小数的截取,再分配位数。
如果位数是正数,就是右对齐。负数,就是左对齐。
其他的也都是相同的规则。
运行结果
C例:
字符型数据输出
#includevoid main() { char c; int a; c = 'A'; a = 66; printf("c=%c, c=%d\n", c, c); printf("a=%c, a=%d\n", a, a); }
分析:
其实这里也就是实现字符和整型的自由转换。
把A变成65,把B变成66.
通过%c和%d来实现是字符,还是整型数值。
运行结果:
D例
字符串型数据输出
#includevoid main() { printf("Who are you?\n"); printf("%s","Why?\n"); }
分析:
基本上也就是“普通字符”输出。
同时也能通过%s的方式输出,一般用于字符串拼接。
运行结果:
E例
多种类型数据输出
#includevoid main() { int a = 15; float b = 123.456; double c = 123456.12345678; char d = 'E'; printf("a=%d,b=%.2f,c=%.4f,d=%c\n", a, b, c, d);}
分析:
基本上就是按照相应是数据类型进行输出。
运行结果:
三、格式输入函数scanf()
1.功能
scanf()函数是通用终端格式化输入函数。
它从标准输入设备(键盘)读取输入的信息。
可以读入任何固有类型的数据自动把数值变换成适当的机内格式。
2.格式
scanf(“格式控制字符串”,地址列表);
3.说明
1)格式控制字符串的含义与printf()类似,它指定输入数据项的类型和格式。
2)地址列表是由若干个地址组成的列表,可以是变量的地址(& 变量名)或者字符串的首地址。
例
使用scanf()函数输入整型数据。
#define _CRT_SECURE_NO_WARNINGS#includevoid main() { int a,b,c; scanf("%d%d%d", &a, &b, &c); printf("%d,%d,%d\n", a, b, c);}
分析:
这里需要注意的是,需要导入第一行。否则会报错。
#define _CRT_SECURE_NO_WARNINGS
然后就是定义3个整型变量,再通过scanf()函数进行输入数据。
运行结果:
或许是scanf()的函数在VS中发生了改变?将scanf()改成scanf_s()函数就不会报错。
如下:
#includevoid main() { int a,b,c; scanf_s("%d%d%d", &a, &b, &c); printf("%d,%d,%d\n", a, b, c);}
运行结果:
而如果什么都不加,也不改成scanf()就会错误提示:
严重性 代码 说明 项目 文件 行 禁止显示状态错误 C4996 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. Project1 D:\VS2019\Project1\Project1\a.c 5
4.补充说明
1)%d%d%d表示要求输入3个十进制整数。
而在输入时,可以用一个空格或多个空格进行分割,也可以使用回车,还可以使用Tab键进行分割。
不能使用逗号进行分割。
2)&是地址运算符
&a指变量a的地址。
scanf()的作用是将键盘输入的数据保存到&a,&b,&c的地址存储单元中,也就成了变量a、b、c。
3)格式化控制字符串由3类字符构成。
格式说明符、空白符、非空白符。
格式说明符
格式字符 | 说明 |
d | 用来输入十进制整数 |
o | 用来输入八进制整数 |
x | 用来输入十六进制整数 |
c | 用来输入单个字符 |
s | 用来输入字符串,将字符串送到一个字符数组中,在输入时以非空白字符开始,以第一个空白字符结束。 字符串以串结束标志\0作为其最后一个字符。 |
f | 用来输入实数,可以用小数形式或指数形式输入。 |
e | 与f作用相同,e与f可以互相替换。 |
空白符:
空白字符会使scanf()函数在读操作中略去输入中的一个或多个空白字符,直到第一个非空白符出现为主。
空白符可以是Space空格、Tab制表符、Enter回车等。
非空白符:
一个非空白符会是scanf()函数在读入时剔除掉与这个非空白符 相同的字符。
5.注意事项
1)scanf()函数中格式控制字符串后面应当是变量地址,而不是变量名。
例:(该例不合法)
scanf(“%d,%d”, a, b);
之所以不合法,问题出现在,a和b上。需要&a和&b。
a和b是变量名,&a和&b才是变量的地址。
2)如果在“格式控制字符串”中除了格式说明意外还有其他字符,则在输入数据时在对应位置应当输入与这些字符相同的字符。
建议不用使用其他的字符。
例:
scanf(“%d,%d,%d”,&a,&b,&c);
在输入时,应该输入1,2,3,而不是1 2 3。
3)在使用“%c”格式输入字符时,空格字符和转义字符都作为有效输入。
%c只要求读入一个字符,后面不需要用空格作为两个字符的间隔。
例:
scanf(“%c%c%c”,&c1,&c2,&c3);
输入“abc”按回车后,变量c1=‘a’,变量c2=‘b’,变量c3=‘c’;
如果输入“a b c”按回车,则变量c1='a',变量c2=‘ ’,变量c3=‘b’;
4)在输入数据时,遇到空格,或按“回车”键,或“空格”键时认为该数据结束。
例:
int a, b, c;
scanf("%d%d%d",&a,&b,&c);
输入“1 2(Tab键)3”后,各变量的值为:a=1,b=2,c=3;
(%d整型和%c字符的获取方式不同。)
5)键盘缓冲区残余信息处理。
A例:
清除缓冲区残余信息
#define _CRT_SECURE_NO_WARNINGS#includevoid main() { int a,b,c; char c1, c2; scanf("%d%d%d", &a, &b, &c); scanf("%c%c", &c1, &c2); printf("a=%d,b=%d,c=%d\n", a, b, c); printf("c1=%c,c2=%c\n", c1, c2);}
分析:
首先是scanf()函数和scanf_s()函数的区别,需要指定字符串长度。
所以这里使用scanf_s()函数会报错。
而scanf()函数又存在问题,所以需要追加一行代码。
然后就是运行结果:
关于c1=,c2=a为什么跟自己认为的不同,是因为c1提前接收了上一行的回车。
解决方法有三种:
第一种是,在两个scanf()函数后面追加fflush(stdin)函数,以清除缓存区的内容,是最稳妥的。
【但我没有调试成功,所以这里就先说明一下。】
第二种是,将第二个字符从scanf()函数中加一个空格。
scanf(" %c%c", &c1,&c2);
这样就可以把回车忽略掉,并正常打印。
第三种是,在第二个scanf()函数前加一个getchar()。
scanf("%d%d%d", &a, &b, &c); getchar(); scanf("%c%c", &c1,&c2);
可以通过这个getchar()函数接收缓冲区中的字符。
B例
多种类型数据输入
#define _CRT_SECURE_NO_WARNINGS#includevoid main() { int a,b; char c1, c2; long x; float y; double z; printf("输入两个字符"); scanf("%c%c", &c1, &c2); printf("输入两个整数"); scanf("%d%d", &a, &b); printf("输入一个长整型"); scanf("%ld", &x); printf("输入一个单精度类型"); scanf("%f", &y); printf("输入一个双精度类型"); scanf("%lf", &z); }
分析:
这里没有进行打印,所以只是输入。
所以先定义变量,然后通过printf进行提示,再通过scanf进行输入。
运行结果:
四、字符数据输入函数getchar()
1.功能
getchar()函数是从键盘上读入一个字符或者从缓冲区中得到一个字符。
getchar()函数等待用户从键盘输入字符,直到按回车健才能结束。
按回车健前的所有输入字符都会逐个显示在屏幕上,但只有第一个字符作为函数的返回值。
2.格式
getchar();
3.说明
1)getchar()与scanf()作为输入函数的区别是:
getchar()只能输入单个字符,scanf()可以输入各种类型数据。
2)经常通过getchar()函数,利用其等待用户输入字符,实现暂停的功能,便于程序调试。
A例
利用getchar()函数输入字符,printf()函数输出字符。
#includevoid main() { char c; c = getchar(); printf("%c",c);}
分析:
首先定义一个字符,然后通过getchar()函数进行字符输入。
最后打印输出。
运行结果
五、字符数据输出函数putchar()
1.功能
putchar()函数每次输出一个字符。
2.格式
putchar(c);
3.说明
c为可以字符变量或者整型变量。
putchar()与printf()的区别就是前者只能输出一个字符,后者可以输出任意类型的数据。
A例
利用getchar()函数输入字符,putchar()函数输出字符。
#includevoid main() { char c; printf("输入一个字符:"); c = getchar(); putchar(c);}
分析:
用getchar()函数输入字符,用putchar(c)函数输出字符。
运行结果