3.3.3 数据的输入函数
1.getchar函数
getchar函数的功能是从键盘上输入一个字符,其一般形式为:
getchar();
通常把输入的字符赋予一个字符变量,构成赋值语句,例如:
char c; c=getchar();
使用该函数前必须要用文件包含命令:#include<stdio.h>或 #include "stdio.h"。
【例3.3】 getchar函数的用法。
程序如下:
1 #include<stdio.h> 2 void main() 3 { 4 char c; 5 printf("input a character\n"); 6 c=getchar(); 7 putchar(c); 8 }
程序的运行结果如下:
input a character >a ↙ a
程序的第5行是输入提示,用来在显示器上显示一条信息,告诉使用程序的人该如何做。建议读者在编程时注意使用这一方法。程序的第6行利用getchar函数从键盘上输入一个字符,并赋给字符变量c。程序运行时,显示一个光标,用户输入的字符(这里是字母“a”)将显示在光标位置(参见运行结果的第2 行),当用户按回车键时,获得输入的字符,结束getchar函数的调用,并把结果赋给变量c。程序的第7行利用putchar函数将字符变量c的值显示在屏幕上。
应该注意的是,getchar函数只能接受单个字符,输入多于一个字符时,只接收第一个字符。这是因为,getchar函数是从键盘缓冲区中读取字符数据的,用户输入的字符暂时存在键盘缓冲区中,形成一个序列。每调用一次getchar函数,将顺序读取一个字符,其他字符还将保留在缓冲区中。
【例3.4】 用getchar函数读取多个字符。
程序如下:
1 #include<stdio.h> 2 void main() 3 { 4 char c; 5 printf("input some characters\n"); 6 c=getchar(); 7 putchar(c); 8 c=getchar(); 9 putchar(c); 10 c=getchar(); 11 putchar(c); 12 }
程序的运行结果可能是:
input some characters abcd ↙ (这里连续输入4个字符) abc (仅显示3个字符,且连续输出)
程序中(第6~11行),getchar函数和putchar函数是交替使用的,但上面的运行结果显示的输入和输出却是分别进行的,为什么?请读者自己体会个中的缘由。读者不妨尝试一下其他不同的输入方法,观察结果有什么不同。
需要注意的是,使用getchar函数可以输入任意字符,包括空格、Tab键、回车等控制字符。
2.scanf函数
(1)scanf函数的调用方法
scanf函数的一般形式为:
scanf(格式控制,地址表列);
其中,“格式控制”的含义同printf函数,“地址表列”是由若干个内存地址组成的表列,可以是变量的地址,也可以是字符串的首地址,等等。
对于变量v,其地址可以用&v表示,其中“&”是地址运算符(详见第7章)。
这里需要读者特别注意,scanf函数的参数除了第一个参数是“格式控制”字符串外,其他都是变量的地址,不是变量名称,这不同于其他程序设计语言。对于一般变量,出现在scanf函数参数中时,通常需要加地址运算符“&”。但有些参数本身就是地址,也就不需要加地址运算符了,比如用指针变量作为参数。
例如:
int a,b,c; scanf("%d%d%d",&a,&b,&c); /* &a、&b、&c分别代表变量a、b、c在内存中的地址*/ printf("%d%d%d\n",a,b,c);
运行时输入:
>1 2 3 ↙
则输出结果为:
123
程序中scanf函数的作用是,将用户输入地数据(这里是1、2、3三个整数,存放在键盘缓冲区中)按顺序存入变量a、b、c在内存中的存储单元(用地址指定)中。格式控制“%d%d%d”表示按十进制整数形式输入3个整数。输入这3个数据时,可以用一个或多个空格将它们隔开,也可以用回车键和跳格键(即Tab)作为分隔符。
对于这段程序,下面的输入方式都是合法的:
① 1 _ 2 _ _ _ _ 3 ↙
② 1 ↙
2↙
3↙
③ 1 → 2 _ _ 3 ↙
再看一个输入实型和字符型数据的例子:
float x,y,z; char c1,c2; scanf("%f%f%f",&x,&y,&z); scanf("%c%c",&c1,&c2);
可以按如下形式输入数据:
1.0 2 .3 ↙ (小数的输入比较自由) ab ↙
其中,“%f”用来输入实型数据,输入多个实数时同样可以使用空格、回车键和Tab键作为分隔符。“%c”用来输入一个字符型数据,输入多个字符时不需要任何分隔符,连续输入即可。
(2)scanf函数的输入格式控制
与printf函数不同,scanf函数的格式控制字符串中,所有项目都是要求用户在运行程序时输入的,包括与格式说明对应的数据和普通字符。
例如,对于如下程序段(假设x、y都是整型的):
printf("input data here:\n"); scanf("x=%d",&x); scanf("y=%d",&y); printf("x=%d,y=%d\n",x,y);
运行时的输入、输出是:
input data here: x=123 ↙ y=456 ↙ x=123,y=456
如果不输入“x=”、“y=”,程序就会出错。因此,通常不在scanf函数的“格式控制”中使用“普通字符”,以避免输入困难。
而与printf函数中的格式说明类似,scanf函数的格式说明也以“%”开始,以一个格式字符结束,中间可以插入附加格式说明字符。表3.3列出了scanf函数所用到的格式字符,表3.4列出了scanf函数可以使用的附加格式说明字符。
表3.3 scanf函数的格式字符
表3.4 scanf函数的附加格式说明字符
说明:
① C语言中,要连续输入2个以上的数据,一般使用空白(即空格、Tab键或回车键)作为分隔符。但有的人习惯使用逗号“,”分隔数据,为此,可以在scanf函数的“格式控制”字符串中,用逗号分隔对应的格式说明,例如:
scanf("%d,%d",&a,&b);
输入时,应采用如下形式:
1,2 ↙
注意,1后面是逗号,它与scanf函数中格式控制中的逗号相对应。如果输入时不用逗号而用空格或其他字符,将不能输入正确的数据。
反过来,如果“格式控制”字符串中没有出现逗号分隔符,输入时用逗号分隔也是错误的。因此,一个好的习惯是,在程序中用提示信息提醒用户该如何输入数据。例如:
printff("输入用逗号分开的两个整数\n"); scanf("%d,%d",&a,&b);
② 用“%c”输入字符时,空格、Tab、回车及其他控制字符都可以作为有效字符输入。因此,对于:
scanf("%c%c%c",&c1,&c2,&c3);
如果输入:
a b c ↙ (3个字母间各有一个空格)
则字符'a'送给变量c1,' '(空格)送给变量c2,'b'送给变量c3。
由于c格式符的特殊性(其他格式符都把空白看做数据的分隔符,而不会读取空白),使用scanf时,最好不要将c格式符与其他格式符混合使用,以免造成输入错误。
③ 在输入数据时,遇到以下情况则认为该数据结束。
● 遇到空格、回车、Tab键。
● 以满足宽度限制,比如对于“%5d”,只取5位整数。
● 遇到非法输入,比如“a”不是合法的十进制数,但是合法的十六进制数。
例如,对语句:
scanf("%d%c%f",&x,&y,&z);
如果输入的是:
56t8o.34↙ (结果x为56,y为't',z为8)
则对应第一个格式%d输入56之后遇到字母t,便认为第一个数据到此结束,把56送给变量x。字符 't' 送给变量y,由于%c只要求输入一个字符,因此“t”后面不需要空格,后面的数值应送给变量z。如果由于疏忽把本来应为80.34的数错输入成8o.34,则由于8后面出现字符o,就认为此数值结束,将8送给z,多余部分自动舍弃。
④ 标准C在scanf函数中不使用%u说明符,对unsigned型数据,以%d或%o、%x格式输入。
⑤ 输入数据时不能规定精度,形如"%8.2f"的格式说明是错误的。
⑥ 可以指定输入数据所占的列数,系统自动按此列数截取所需数据。例如:
scanf("%3d%3d",&a,&b);
如果输入:
12345↙
则系统自动将123赋给a,45赋给b。
⑦“%”后的“*”附加说明符,用来表示跳过相应的数据。在利用现成的一批数据时,如果不需要其中的某些数据,则可以利用此种方法。例如:
scanf("%2d%*3d%2d",&a,&b);
如果输入以下信息:
1234567↙
则将12赋给变量a,67赋给变量b。第二个数据345被跳过不赋给任何变量。
【例3.5】 求任意两个整数的和。
分析:如果问题中出现“任意”等字眼,通常意味着,程序所处理的数据是在运行程序时从键盘输入的。输入整数的方法是调用scanf函数。
程序的算法过程可用图3.2表示。
图3.2 求任意两个整数的和
源程序如下:
1 #include <stdio.h> 2 void main() 3 { int a,b,sum; 4 printf("输入用逗号分隔的两个整数:"); /* 输入提示 */ 5 scanf("%d,%d",&a,&b); /* 格式输入语句 */ 6 sum=a+b; /* 赋值语句 */ 7 printf("%d和%d的和是%d",a,b,sum); /* 格式输出语句 */ 8 }
程序的运行结果如下:
输入用逗号分隔的两个整数:3, 5↙ 3和5的和是8