第4讲 标准输入输出函数举例解读.docx
- 文档编号:23581290
- 上传时间:2023-05-18
- 格式:DOCX
- 页数:25
- 大小:62.75KB
第4讲 标准输入输出函数举例解读.docx
《第4讲 标准输入输出函数举例解读.docx》由会员分享,可在线阅读,更多相关《第4讲 标准输入输出函数举例解读.docx(25页珍藏版)》请在冰豆网上搜索。
第4讲标准输入输出函数举例解读
第4讲标准输入输出函数举例
教学过程设计
一讲授新课
所谓输入输出是以计算机主机为主体而言的。
从计算机向外部输出设备(例如:
显示屏、打印机、磁盘等)输入数据称为“输出”,从外部向输入设备(例如:
键盘、磁盘、光盘、扫描仪等)输入数据称为“输入”。
本讲中将要介绍的putchar、getchar、printf、scanf函数都是标准输入输出函数,所以在主调函数调用这些标准函数之前需要用文件包含预处理命令将头文件stdio.h(stdio.h是standardinput&output的缩写,它包含了与标准I/O库有关的变量定义和宏定义。
)包含到主调函数所在的文件中来。
考虑到printf和scanf函数使用频繁,系统允许在使用这两个函数时可不加编译预处理命令。
1字符输出函数putchar
1.1putchar函数的函数原型
putchar函数的函数原型是:
intputchar(char/intch);,其中:
参数ch可以是字符型变量或整型变量,表示一个输出的字符。
返回值为int型,表示输出字符的ASCII码值,但若出错,则返回EOF。
1.2putchar函数的功能
在stdout上输出一个字符。
2字符输入函数getchar
2.1getchar函数的函数原型
getchar函数的函数原型是:
intgetchar(void);,其中:
返回值为int型,表示用户输入的第一个字符的ASCII码值,但若文件结束或出错,则返回-1,且将用户输入的字符回显到屏幕。
2.2getchar函数的功能
从stdin流中读入一个字符。
当键盘缓冲区中没有字符时,程序调用getchar函数后,就等待用户按键。
用户输入的字符被存放在键盘缓冲区中,直到用户按回车键(回车字符也放在缓冲区中)才从键盘缓冲区中读取一个字符。
如果用户在按回车键之前输入了不止一个字符,除了第一个字符的其他字符仍会保留在键盘缓存区中,等待后续getchar函数的调用来读取,后续getchar函数被调用后不会等待用户按键,而是直接读取键盘缓冲区中的字符,直到键盘缓冲区中的字符读完为止。
例如:
#include
main()
{
charch;
while((ch=getchar())!
='\n')
{
if(ch>='A'&&ch<='Z')
ch=ch+32;
elseif(ch>='a'&&ch<='z')
ch=ch-32;
printf("%c",ch);
}
}
执行以上程序时,如果从键盘上输入ABCdef↙,则输出为(abcDEF)。
3格式输出函数printf
3.1printf函数的函数原型
printf函数的函数原型是:
intprintf(char*format[,arg1,arg2,...,argn]);(其中[]表示可选项。
),其中:
与形参arg1,arg2,...,argn所对应的实参可以是值为基本类型的表达式、字符串常量、字符指针变量或字符数组的起始地址,叫做输出列表,表示一些由输出格式控制字符串中与其位置相对应的输出格式控制字符指定输出格式的格式输出数据。
与形参format所对应的实参可以是一个字符串常量、字符指针变量或字符数组的起始地址,该字符串常量、字符指针变量所指向的字符串或字符数组中存储的字符串叫做输出格式控制字符串。
注意:
输出列表中的各个参数的数据类型要与输出格式控制字符串中与其位置相对应的输出格式控制字符一致,否则会得不到正确结果或导致执行错误。
返回值为int型,表示输出字符的个数,但若出错,则返回负数。
3.2输出格式控制字符串、普通字符和输出格式控制字符
3.2.1输出格式控制字符串
输出格式控制字符串由普通字符和输出格式控制字符两部分组成。
3.2.2普通字符
原样输出的字符。
但如果要输出字符“%”,则应该用“%%”表示。
3.2.3输出格式控制字符
输出格式控制字符是输出格式控制字符串中的重要组成部分。
输出格式控制字符的一般形式是“%+[附加输出格式说明符]+输出格式说明符”(其中[]表示可选项。
)。
输出格式控制字符的功能是指出输出列表中与其位置相对应的参数的值的输出格式。
注意:
输出列表中的各个参数的数据类型要与输出格式控制字符串中与其位置相对应的输出格式控制字符一致,否则会得不到正确结果或导致执行错误。
printf函数的输出格式说明符
输出格式说明符
说明
d
把内存中的二进制补码(所取位数还需要参考附加输出格式说明符字母l。
)输出为一个带符号(二进制补码的最高位被当作符号位。
)的十进制形式的整型数据。
正数不输出符号。
u
把内存中的二进制补码(所取位数还需要参考附加输出格式说明符字母l。
)输出为一个无符号(二进制补码的最高位被当作数值位。
)的十进制形式的整型数据。
o
把内存中的二进制补码(所取位数还需要参考附加输出格式说明符字母l。
)输出为一个无符号(二进制补码的最高位被当作数值位。
)的八进制形式的整型数据。
不输出前导符0。
x,X
把内存中的二进制补码(所取位数还需要参考附加输出格式说明符字母l。
)输出为一个无符号(二进制补码的最高位被当作数值位。
)的十六进制形式的整型数据。
不输出前导符0x。
若用x,则输出十六进制数的数码a~f时以小写形式输出;若用X,则输出十六进制数的数码a~f时以大写形式输出。
c
把内存中的二进制补码输出为一个字符。
不输出单引号。
s
把内存中的二进制补码输出为一个字符串。
不输出双引号。
f
把内存中的二进制补码输出为一个小数形式的实型数据。
整数部分全部如数输出,小数点占1位,小数部分的位数还需要参考附加输出格式说明符n。
注意:
并非全部数字都是有效数字!
例如:
单精度实数的有效位数一般为7位,双精度实数的有效位数一般为16位。
e,E
把内存中的二进制补码输出为一个指数形式的实型数据。
数值为规范化的指数形式(即在字母e(或E)之前的小数部分中,小数点左边应有且只能有1位非零的数字)。
尾数的整数部分占1位,小数点占1位,小数部分的位数还需要参考附加输出格式说明符n,e占1位,指数的符号占1位,数值占3位。
若用e,则输出的指数以“e”表示。
若用E,则输出的指数以“E”表示。
注意:
并非全部数字都是有效数字!
printf函数的附加输出格式说明符(出现顺序一般为[-][m][.n][l])
附加输出格式说明符
说明
-
与附加输出格式说明符m配合使用。
有-,表示若数据的实际输出列宽小于m,则在m列范围内,数据左对齐,右补空格以凑够指定输出列宽m;无-,表示若数据的实际输出列宽小于m,则在m列范围内,数据右对齐,左补空格以凑够指定输出列宽m。
m(m为正整数)
有m,表示指定数据的最小输出列宽:
若数据的实际输出列宽大于m,则突破m的限制,按实际输出列宽将数据全部输出;若数据的实际输出列宽小于m,则将数据全部输出在m列范围内,至于数据是左对齐还是右对齐,以及是右补空格以凑够指定输出列宽m还是左补空格以凑够指定输出列宽m,还需要参考附加输出格式说明符-。
无m,按实际输出列宽将数据全部输出。
.n(n为正整数)
与输出格式说明符f、e(E)、s配合使用。
与输出格式说明符f、e(E)配合使用时:
有n,表示输出该实型数据的n位小数;无n,默认小数部分占6位。
与输出格式说明符s配合使用时:
有n,表示截取该字符串中的n个字符,作为该字符串的实际输出列宽;无n,该字符串的实际输出列宽不变。
字母l
与输出格式说明符d、u、o、x(X)配合使用。
有字母l,则取内存中的二进制补码的32位;无字母l,则取内存中的二进制补码的16位。
3.3输出时的类型转换
转换的规则类似于“赋值运算中的自动类型转换”的规则,这里不再说明。
风格:
输出列表中的各个参数的数据类型要与输出格式控制字符串中与其位置相对应的输出格式控制字符一致,否则会得不到正确结果或导致执行错误。
3.4printf函数的功能
printf函数的功能是按format指向的格式控制字符串所规定的格式,将输出表列的值(基本类型或字符串常量)输出到标准输出设备。
当执行printf函数时,会按照“输出格式控制字符串”内从左到右输出格式控制字符和普通字符出现的顺序依次向显示器输出信息:
碰到输出格式控制字符,则按照其指定的格式要求输出列表中与其位置相对应的参数的值;碰到普通字符则原样输出,…,直到遇到“输出格式控制字符串”的字符串结束标志'\0'为止。
最后再一次强调:
输出列表中的各个参数的数据类型要与输出格式控制字符串中与其位置相对应的输出格式控制字符一致,否则会得不到正确结果或导致执行错误。
4格式输入函数scanf
4.1scanf函数的函数原型
scanf函数的函数原型是:
intscanf(char*format[,arg1,arg2,...,argn]);(其中[]表示可选项。
),其中:
与形参arg1,arg2,...,argn所对应的实参可以是值为基本类型的表达式、字符串常量、字符指针变量或字符数组的起始地址,叫做输出列表,表示一些由输出格式控制字符串中与其位置相对应的输出格式控制字符指定输出格式的格式输出数据。
与形参format所对应的实参可以是一个字符串常量、字符指针变量或字符数组的起始地址,该字符串常量、字符指针变量所指向的字符串或字符数组中存储的字符串叫做输出格式控制字符串。
形参arg1,arg2,...,argn是指针,与形参arg1,arg2,...,argn所对应的实参可以是变量的地址、字符指针变量或字符数组的起始地址(例如:
字符数组名),叫做输入地址列表,该变量的内存单元、字符指针变量或字符数组的起始地址所指向的内存单元用于接收一些由输入格式控制字符串中与其位置相对应的输入格式控制字符指定输入格式的格式输入数据。
与形参format所对应的实参可以是一个字符串常量、字符指针变量或字符数组的起始地址,该字符串常量、字符指针变量所指向的字符串或字符数组中存储的字符串叫做输入格式控制字符串。
注意:
输入地址列表中的各个参数所指向的内存单元中的数据的数据类型要与输入格式控制字符串中与其位置相对应的输入格式控制字符一致,否则会得不到正确结果或导致执行错误。
返回值为int型,表示读入并赋给输入地址列表的数据个数,遇文件结束返回EOF,出错返回0。
4.2输入格式控制字符串、普通字符和输入格式控制字符
4.2.1输入格式控制字符串
输入格式控制字符串由普通字符和输入格式控制字符两部分组成。
4.2.2普通字符
原样输入的字符。
4.2.3输入格式控制字符
输入格式控制字符是输入格式控制字符串中的重要组成部分。
输入格式控制字符的一般形式是“%+[附加输入格式说明符]+输入格式说明符”(其中[]表示可选项。
)。
输入格式控制字符的功能是指出输入地址列表中与其位置相对应的参数所指向的内存单元所接收的数据的输入格式。
注意:
输入地址列表中的各个参数所指向的内存单元中的数据的数据类型要与输入格式控制字符串中与其位置相对应的输入格式控制字符一致,否则会得不到正确结果或导致执行错误。
scanf函数的输入格式说明符
输入格式说明符
说明
d
把输入序列看作带符号的十进制形式的整型数据输入。
u
把输入序列看作无符号的十进制形式的整型数据输入。
o
把输入序列看作无符号的八进制形式的整型数据输入。
x,X
把输入序列看作无符号的十六进制形式的整型数据输入。
c
取输入序列中的一个字符输入。
s
把输入序列看作字符串输入。
f
或
e,E
把输入序列看作实型数据输入。
scanf函数的附加输入格式说明符(出现顺序一般为[*][m][l])
附加输入格式说明符
说明
*
输入赋值抑制符。
表示该格式说明要求输入数据,但跳过它指定的列数,不赋给输入地址列表中与其位置相对应的地址,即在地址列表中没有对应的地址项,相当于空读一个数据。
m(m为正整数)
输入列宽指示符。
表示指定数据的最大输入列宽。
如遇空格或不可转换的字符,读入的列数将减少。
字母l
把输入序列看作长整型数据(可用%ld,%lu,%lo,%lx,%lX)或双精度型数据(可用%lf,%le)。
4.3输入数据的分隔
在输入数据时,遇到下列情况时结束一个数据的输入(不是结束该scanf函数,scanf函数仅在输入地址列表中的每一个数据域均有数据,并按回车后结束):
遇空格,或按下回车键或跳格键。
例如:
"%d%d%d"表示按十进制整数形式输入数据。
输入数据时,在两个数据之间以一个或多个空格间隔,也可以用回车键、跳格键。
下面输入均为合法:
13︼4︼5↙
23︼︼4︼︼︼︼5↙
33↙
4︼5↙
43(按跳格键)4↙
5↙
注意:
用"%d%d%d"格式控制输入数据时,不能用逗号作两个数据间的分隔符,如输入:
3,4,5↙不合法。
用带一个“%s”的scanf函数接收有空格的字符串
charstr[13];
scanf("%s",str);
输入:
Howareyou?
↙,scanf函数扫描到“How”后面的空格就认为对str的赋值结束,并忽略后面的“areyou?
”。
这里要注意的是“areyou?
↙”还在键盘缓冲区中。
所以实际上并不是把Howareyou?
这12个字符加上'\0'送到数组str中,而只将空格前的字符How送到数组str中,由于把How作为一个字符串处理,因此在其后加'\0'。
数组str状态见下图。
H
o
w
\0
解决方法1,调用一次scanf函数:
#include
main()
{
charstr1[80],str2[80],str3[80];
scanf("%s%s%s",str1,str2,str3);
printf("%s%s%s",str1,str2,str3);
}
解决方法2,多次调用scanf函数:
#include
main()
{
charstr1[80];
charstr2[80];
charstr3[80];
scanf("%s",str1);
scanf("%s",str2);
scanf("%s",str3);
printf("%s",str1);
printf("%s",str2);
printf("%s",str3);
}
输入:
Howareyou?
↙后,str1、str2、str3的数组状态如下图所示。
数组中未被赋值的元素的值是不可预料的。
所以得到一个结论是:
带一个“%s”的scanf函数不能正确接收有空格的字符串!
最后要注意:
在用%c格式输入字符时,空格字符和转义字符都作为有效字符输入。
例如:
charc1,c2,c3;
scanf("%c%c%c",&c1,&c2,&c3);
输入:
a︼b︼c↙,字符a送给c1,字符︼送给c2,字符b送给c3。
这是因为%c只要求读入一个字符,后面不需要用空格作为两个字符的间隔,因此︼作为下一个字符送给c2。
scanf函数留下的“垃圾”
我们知道:
在用%c格式输入字符时,空格字符和转义字符都作为有效字符输入,而不能作为输入数据的分隔。
当使用2个scanf函数连续给2个变量赋值且第二个scanf函数要求输入字符时,例如:
main()
{
charc1,c2;
scanf("%c",&c1);
scanf("%c",&c2);
printf("c1is%c,c2is%c.",c1,c2);
}
运行该程序,输入一个字符A后回车(要完成scanf函数必须输入回车),在执行scanf("%c",&c1);时,给变量c1赋值A,但回车符仍留在输入缓冲区内;在执行scanf("%c",&c2);时,变量c2将接收到一个回车符而使输入结束,输出结果见下图。
如果输入AB后回车,那么输出结果为:
c1isA,c2isB.。
解决方法:
用函数getchar()接收回车符。
用函数fflush(stdin)清除全部剩余内容。
用输入格式控制字符串中的空格或%*c跳过回车符。
#include
main()
{
charc1,c2;
scanf("%c",&c1);
getchar();
scanf("%c",&c2);
printf("c1is%c,c2is%c.",c1,c2);
}
#include
main()
{
charc1,c2;
fflush(stdin);
scanf("%c",&c1);
fflush(stdin);
scanf("%c",&c2);
printf("c1is%c,c2is%c.",c1,c2);
}
#include
main()
{
charc1,c2;
scanf("%c",&c1);
scanf("%c",&c2);或scanf("%*c%c",&c2);
printf("c1is%c,c2is%c.",c1,c2);
}
遇输入列宽指示符。
可以指定输入数据所占列数,系统自动按它截取所需数据,此时无需其它分界符。
例如:
inta,b;
scanf("%3d%3d",&a,&b);
输入:
123456↙,系统自动将123赋给a,456赋给b。
charc;
scanf("%3c",&c);
输入:
abc↙,从键盘连续读入3个字符abc,由于c只能容纳一个字符,系统就把第一个字符a赋给c。
charc1,c2;
scanf("%3c%2c",&c1,&c2);
输入:
abcde↙,先读入3个字符abc,将其赋给c1,由于c1只能容纳一个字符,系统就把第一个字符a赋给c1;再读入2个字符de,将其赋给c2,由于c2只能容纳一个字符,系统就把第一个字符d赋给c2;最后读入↙,由于c1、c2都被赋值,所以此时遇到↙便结束scanf函数。
inta,b;
scanf("%2d︼%*3d︼%2d",&a,&b);
输入:
12︼345︼67↙,先将12赋给a,%*3d表示读入3位整数但不赋给任何变量,最后读入2位整数67赋给b。
遇非法输入。
例如:
inta;
charb;
floatc;
scanf("%d%c%f",&a,&b,&c);
输入:
1234a123o.26↙,第一个数据对应%d格式在输入1234之后遇字母a,因此认为数值1234后已没有数字了,第一个数据到此结束,把1234送给变量a。
字符a送给变量b,由于%c只要求输入一个字符,因此输入字符a之后不需要加空格,后面的数值应送给变量c。
如果由于疏忽把本来应为1230.26错打成123o.26,由于123后面出现字母o,就认为该数值数据到此结束,将123送给c。
利用输入格式控制字符串中的普通字符。
例如:
inta,b;
scanf("%d,%d",&a,&b);
输入:
3,4↙是合法的,但输入:
3︼4↙是非法的。
4.4scanf函数的功能
scanf函数的功能是从标准输入设备按format指向的格式控制字符串所规定的格式,输入数据赋给输入地址列表所指向的内存单元。
当键盘缓冲区中没有数据时,程序调用scanf函数后,会等待用户通过键盘键入值,要求用户按照“输入格式控制字符串”内从左到右输入格式控制字符和普通字符出现的顺序依次从键盘键入值,碰到输入格式控制字符,则要求用户键入变量值,碰到普通字符,则要求用户原样输入该字符。
scanf函数在未能按照“输入数据的分隔”方法为当前将要赋值的变量分离出“变量输入值”(我们把用户通过键盘输入的变量值称为“变量输入值”。
)时,会将用户输入的数据临时存放在键盘缓冲区中,对于用户键入的普通字符,scanf函数会略过;一旦为当前将要赋值的变量分离出来“变量输入值”,scanf函数就会根据“输入格式控制字符串”内对应的“输入格式控制字符”的格式要求将这些“变量输入值”看作“符合格式要求的值”赋值给当前将要赋值的变量做其内存补码值。
当所有指定的变量都得到值时,一旦遇到回车,scanf就不再等待用户输入而结束。
当键盘缓冲区中有数据时,程序调用scanf函数后,不会等待用户按键,而是直接读取键盘缓冲区中的数据,直到键盘缓冲区中的数据读完为止。
最后再一次强调:
输入地址列表中的各个参数所指向的内存单元中的数据的数据类型要与输入格式控制字符串中与其位置相对应的输入格式控制字符一致,否则会得不到正确结果或导致执行错误。
二布置作业
作业:
1)选择题:
1.运行以下程序,如果从键盘上输入ab↙c↙def↙,则输出结果为()。
#include
#defineN6
main()
{
charc[N];
inti=0;
for(;i ; for(i=0;i putchar(c[i]); printf("\n"); } A.a b c d e f B.a b c d C.ab c d D.abcdef 2.以下叙述中正确的是()。 A.输入项可以是一个实型常量,如: scanf("%f",3.5);。 B.只有格式控制,没有输入项,也能正确输入数据到内存,如: scanf("a=%d,b=%d");。 C.当输入一个实型数据时,格式控制部分可以规定小数点后的位数,如: scanf("%4.2f",&d);。 D.当输入数据时,必须指明变量地址,如: scanf("%f",&f);。 3.执行下列程序时输入: 123︼456︼789↙,输出结果是()。 main() { chars[100]; intc,i; scanf("%c",&c); scanf("%d",&i); scanf("%s",s); printf("%c,%d,%s\n",c,i,s); } A.123,456,789B.1,456,789C.1,23,456,789D.1,23,456 4.下列程序执行后的输出结果是()。 main() { charx=0xFFFF; printf("%d\n",x--); } A.-32767B.FFFEC.-1D.-32768 5.以下程序的输出结果为()。 main() { unsignedinta=65535; intb=-2; printf("\na=%d,%u;b=%d,%u",a,a,b,b); } A.-1,65535;-2,65534B.65535,65535;-2,65534 C.65535,65535;65534,65
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第4讲 标准输入输出函数举例解读 标准 输入输出 函数 举例 解读