3.2 数据的输入和输出
将数据通过计算机外部设备送到计算机内存中的操作称为输入,反之,将数据从计算机内存送到计算机外部设备的操作称为输出。
首先说明,C语言本身不提供输入/输出语句,它的输入/输出操作都是通过调用C语言系统提供的输入/输出标准函数来实现的。这些输入/输出标准函数被存放在标准函数库中,如果要使用这些输入/输出函数,必须要求在源程序的开始包含预处理命令:#include "stdio.h"(关于C语言的预处理功能详见第7章)。在这里,系统默认的标准输入/输出设备是键盘和显示器。
本节主要介绍两类常用的标准输入/输出函数:一类是用于单个字符的输入/输出函数getchar( )和putchar( ),另一类是用于格式输入/输出的函数scanf( )和printf( ),其中最后一个字符f是format的缩写,即格式的意思。
3.2.1 字符输入函数getchar( )
getchar( )函数调用的一般形式为:
getchar( )
该函数的功能是从标准输入设备(键盘)上输入一个字符,按回车键后,getchar( )将接收该字符作为函数的值。通常将getchar( )函数得到的值通过赋值运算符赋给某个字符型变量。
例如:
char ch; ch=getchar( ); ch++;
当程序执行到“ch=getchar( );”语句时,程序会暂停,等待用户从键盘输入一个字符,然后继续执行后面的语句。
注意:getchar( )只能接收一个字符,而且只有在用户按回车键<Enter>后,读入才开始执行。
3.2.2 字符输出函数putchar( )
putchar( )函数调用的一般形式为:
putchar(ch)
函数的功能是向标准输出设备(显示器)输出一个字符(即ch的值),其中,ch可以是字符型常量、变量或整型变量。
【例3.1】 字符输出函数示例。
#include "stdio.h" main( ) { char a,b,c; a='T';b='e';c='a'; putchar(a);putchar(b);putchar(c); }
程序运行结果为:
Tea
putchar( )函数也可以输出转义字符,例如,putchar('\n') 输出一个换行符。如果将例3.1中程序的最后一行改为:
putchar(a);putchar (b);putchar ('\n'); putchar (c);
则输出结果为:
Te a
还可以输出其他转义字符,例如:
putchar('\102'); /* 输出字符“B” */ putchar('\"); /* 输出单引号字符“ ' ” */ putchar('\015'); /* 输出回车,不换行 */
【例3.2】 从键盘输入一个字符并显示该字符。
#include "stdio.h" main( ) { char ch; ch=getchar( ); putchar(ch); }
该程序在运行到“ch=getchar( );”语句时会暂停下来,等待用户从键盘上输入一个字符。如果用户从键盘输入字符“c”并按回车键(用<Enter>表示回车键),就会在屏幕上看到字符c。执行情况如下:
c <Enter> c
注意:getchar( )函数得到的字符可以赋给一个整型变量或字符型变量,也可以不赋给任何变量而作为表达式的一部分。例如,可以将例3.2程序中的第5行和第6行用下面的语句代替:
putchar(getchar( ));
3.2.3 格式输出函数printf( )
putchar( )函数只能输出单个字符。如果用户在程序中需要输出若干个任意类型的数据,就要使用在前面章节中用到的格式输出函数printf( )来实现。printf( )函数在整个C语言程序设计中应用非常广泛,希望读者能够很好地掌握。
1.printf( )函数调用的一般形式
printf( )函数调用的一般形式如下:
printf("控制字符串",输出项列表)
printf( )函数的功能是,按控制字符串规定的输出格式,将输出项列表中的各输出项的值依次输出到系统指定的标准输出设备(显示器)上。
下面分别介绍printf( )函数中各参数的含义。
(1)控制字符串
控制字符串是用双引号括起来的字符串,也称转换控制字符串,它可以包含以下两种信息。
① 格式说明
格式说明由“%”和跟随其后的一个格式字符组成。它的作用是将要输出的数据转换为指定的格式输出。格式说明总是由“%”字符开始,以一个格式字符作为结束,对不同类型的数据应使用不同的格式字符控制其输出格式。C语言提供的格式字符及其功能如表3.1所示。
表3.1 printf( )格式字符及其功能
在一些系统中,这些格式字符只允许使用小写字母,因此建议读者统一使用小写字母,使程序具有通用性。此外,还可以根据需要在“%”和格式字符之间插入“宽度说明”、“左对齐符号-”、“前导零符号0”等附加格式说明,格式为:
%[+][-][0][#][m.n][l]格式字符;
附加格式说明符及其功能如表3.2所示。
表3.2 printf( )附加格式说明字符及其功能
② 普通字符
普通字符是需要原样输出的字符,它包含可打印的字符和不可打印的字符。可打印的字符在“控制字符串”中直接用字符符号表示,如a、b等;不可打印的字符用转义字符表示,如换行'\n',横向跳格'\t',响铃'\a'等。
(2)输出项列表
输出项列表是需要输出的一些数据,可以是一个或者多个输出项。当有多个输出项时,各输出项之间用逗号“,”隔开。输出项可以是常量、变量或表达式。输出项与控制字符串中的格式说明从左到右在类型上必须一一对应匹配。如果不匹配将导致数据不能正确输出。另外,输出项的个数与控制字符串中格式说明的个数应该相同。如果输出项的个数多于格式说明的个数,则多余的输出项不输出;如果输出项的个数少于格式说明的个数,则对于多余的格式说明将输出不定值(或0值)。
2.printf( )函数的调用
printf( )函数的调用可分为以下3种情况。
(1)控制字符串中只有普通字符
此时控制字符串中没有格式说明,也就没有输出项列表这一部分参数,其结果是将该字符串原样显示。例如,下面的程序段:
printf("What is your name? \n"); printf("My name is Li li. \n");
该程序段执行后,屏幕显示:
What is your name? My name is Li li.
这两个printf语句的最后都有一个转义字符“\n”,表示回车换行。其他的则是格式字符串中的普通字符,原样输出。
(2)控制字符串中只有格式说明
此时控制字符串中没有普通字符,只含有格式说明,因此需要有输出项列表这一部分参数。表3.3列举了常用格式字符的各种输出结果。
表3.3 printf( )函数的调用示例
注:已知int a=123,b=-1;float f=12.3456;double d=111.1111111111111;char ch='A'。
(3)控制字符串中既有格式说明又有普通字符
将二者混合使用可使输出结果更清楚,所以是经常采用的一种形式。
【例3.3】 格式输出函数示例
#include "stdio.h" main( ) { int a=5,b=8; printf("%d%d%d\n",a,b,a+b); printf("%d %d %d\n",a,b,a+b); printf("%d,%d,%d\n",a,b,a+b); printf("a=%d,b=%d,a+b=%d\n",a,b,a+b); }
程序运行结果如下:
5813 5 8 13 5,8,13 a=5,b=8,a+b=13
特别强调的是,用printf( )函数输出时,注意输出的数据类型应与上述格式说明匹配,否则将会出现错误。
另外,如果希望输出字符“%”,使用特殊格式说明“%%”。例如:
printf("%d%%\n",10);
执行后将输出:
10%
3.2.4 格式输入函数scanf( )
1.scanf( )函数调用的一般形式
scanf( )函数调用的一般形式为:
scanf (“控制字符串”,输入项地址列表)
scanf( )函数的功能是,按控制字符串规定的输入格式,从系统指定的标准输入设备(键盘)上将输入的数据依次存到输入项地址列表所指定的内存单元中。
其中,输入项地址列表是由若干个地址组成的列表,可以是变量的地址或字符串的首地址等。若为多项,各项之间用逗号隔开。控制字符串的含义与printf( )函数类似,它规定了输入数据的输入格式。它可以包含以下两种信息。
(1)格式说明
与printf( )函数中的格式说明类似,scanf( )函数的格式说明也是以“%”开始,以一个格式字符结束的,中间可以插入附加格式说明符。表3.4中列出了scanf( )函数用到的格式字符,表3.5列出了scanf( )函数可以使用的附加说明符(修饰符)。
表3.4 scanf( )格式字符
表3.5 scanf( )附加的格式说明符
(2)普通字符
普通字符在输入数据时要求原样输入相同的字符。
说明:
① 在VC环境下,输入long整型数据时,在“%”和“d” 之间必须加字母“l”;输入double型数据时,在“%”和“f(e)”之间也必须加“l”,否则得不到正确的数据。
② 当指定输入数据所占的宽度m时,系统自动按宽度m截取所需数据,但不能对实型数据指定小数位的宽度。例如:
scanf ("%6.3f",&a );
是不合法的,不能企图输入以下信息而使a的值为123.456:
123456<Enter>
③ 输入项与控制字符串中的格式说明从左到右在类型上必须一一对应匹配,如果不匹配将得不到正确的数据。另外,输入项的个数与控制字符串中格式说明的个数应该相同。如果输入项的个数多于格式说明的个数时,scanf( )函数结束输入,多余的输入项不会从键盘接收到新的数据;如果输入项的个数少于格式说明的个数,则scanf( )函数同样结束输入。
④ 在输入数据时,遇到下列情况之一时认为该数据结束:
● 空格符(空格键)、制表符(Tab键)或回车符(回车键);
● 宽度结束,如“%2d”,则只取两列;
● 非法输入。
当输入的数据少于输入项的个数时,程序等待输入,直到输入的数据个数与输入项的个数相同为止;当输入的数据多于输入项的个数时,多于的数据将留作下一个输入函数的输入数据。
⑤ 在用“%c”格式输入字符时,空格符、制表符、回车符、转义字符等都是有效字符。但是,如果在格式说明之间加入了空格,这时输入字符中的空格符、制表符和回车符都将作为间隔符。
2.scanf( )函数的调用
scanf( )函数的调用将通过下面的例题来进一步讲解。
【例3.4】 格式输入函数示例。
#include "stdio.h" main( ) { int a,b; char c; scanf("%d%c%d",&a,&c,&b); printf("%d,%d,%c\n",a,b,c); }
程序运行结果如下:
输入:33a66<Enter> (输入a、c、b的值) 输出:33,66,a (输出a、b、c的值)
其中,&a、&b、&c中的&是取地址运算符。&a的含义是a在内存中的地址。例3.4中scanf( )函数的作用是,将从键盘上输入的3个数据33、66、a存入系统为变量a、b、c分配的内存单元中,如图3.1所示。第一个数据对应格式%d输入22之后遇字母a,因此认为数值22后已没有数字了,第1个数据到此结束,把22赋给变量a;第2个数据对应格式%c,因此将字符a赋给变量c;第3个数据66后面是回车键,认为此数值到此结束,则将66赋给变量b。
图3.1 变量a、b、c中的值
表3.6中列举了常用格式字符的各种输入形式及变量获得的值。
表3.6 scanf( )函数的调用示例
注:已知int a,b; float f; double d; char c1,c2。
注意:当调用scanf( )函数从键盘输入数据时,最后一定要按下回车键,scanf( )函数才开始接收从键盘上输入的数据。scanf( )函数中的第二部分参数(即输入项地址表列)应当是变量的地址,而不应是变量名。例如:
int a,b; scanf ("%d,%d",a,b );
是错误的,应将“a,b”改为“&a,&b”。这是初学者常犯的错误!