C语言的输入是由系统提供的库函数完成的。 scanf函数是C语言中最常用、功能最强大的输入函数。 但如果该功能使用不慎,可能会出现错误或者达不到预期的结果。 以下结果基于VC++6.0运行环境。
1、格式说明符与输入项的三种对应关系(类型、数量、顺序)。 scanf函数中的格式描述(“%格式字符”)应与输入项的数据类型一致,编号相同且对应顺序(除描述中出现的附加格式字符外) )。 示例 1: inta,b;scanf("%d%d%d",&a,&b);("%d,%d",a,b); 当输入“345”时,输出“3,4”。 没有错误消息,但第三个数字没有接收到的变量,因此没有输出。 另一个例子是 inta,b;scanf("%d",&a,&b);("%d,%d",a,b); 输入“34”时,输出“3,-”,a得到3,但b是随机数,这是由于格式描述(“%格式字符”)与输入项个数不一致造成的。 另一个例子是 {;[10];;;};scanf("%d,%s,%d,%f",&); 输入“10001,”zhang”,23,68”,运行程序信息时没有出现错误,但无法正确接收输入数据。
应该写成:scanf("%d,%s,%d,%f",&.num,.name,&.age,&stu-dent.score); 确保格式描述和输入项的数量相等且一一对应。 ,这样就可以正确接收输入数据。 示例 2:chara,b;scanf("%d%d",&a,&b);("%d,%d",a,b); 当输入“34”时,输出“3,4”,当输入整个值时,类型数据作为字符类型数据被接收,但结果是正确的,因为字符类型数据作为整数数据存储在内存中。 再例如,b;scanf("%d%d",&a,&b);("%d,%d",a,b); 当输入“34”时,输出“0”,即a和b的差值结果都是随机数,这是由于输入格式和接收的数据类型不同造成的。 又如: inta,b;scanf("%f%f",&a,&b);("%d,%d",a,b); 当输入“1.23.4”时,输出“,”,即 a 和 b 的结果都是随机数,这也是输入格式和接收数据类型不同造成的。
2. 非格式说明符的输入 非格式说明符要求用户按原样输入,不能更改或省略。 示例 1: inta,b;scanf("a=%d,b=%d",&a,&b);("%d,%d",a,b); 输入“12”(即1和2之间用空格分隔),输出“-,-”,没有错误信息,但结果与输入数据不一致,a和b的输出值为随机数。 这是因为scanf函数中设置的格式(“a=%d,b=%d”)(其中a=,b=为普通字符)与输入数据的格式不一致(1和2之间用分隔符分隔)空格)因此,正确的输入形式应该是“a=1,b=2”(“,”一定不能漏掉)。 因此,为了保证数据输入正确,在输入数据之前,首先检查程序中scanf函数设置的格式,然后按照设置的格式正确输入数据。 示例2:scanf("%d,%d",&a,&b); 输入时应采用如下形式:3,4↙注意3后面要跟一个逗号,对应scanf函数中“格式控制”中的逗号。 不输入逗号但输入空格或其他字符是不正确的。 3□4↙(错误)3:4↙(错误) 如果是scanf("%d□□%d",&a,&b);,输入时两个数据之间必须有两个或多个空格字符。 如:3□□4↙或3□□□□4↙
3. 附加格式说明符示例 1: inta,b;scanf("%2d%2d",&a,&b);("%d,%d",a,b); 输入“1234”,输出“12,34” 输入“123”,输出“12,3” 输入“”,输出“12,34”,因为格式中的“d”格式字符表示输入的是整数数据,并且“2”附加格式描述字符表示输入数据。 宽度为2,所以无论用户输入什么,系统都会自动截取两位并将其分配给a,然后截取两位并将其分配给b。 也就是说,可以使用附加的格式说明符来指定输入数据占用的列数,系统会根据其自动截取所需的数据。
另一个例子是 scanf("%3c",&ch); 如果从键盘连续输入三个字符abc,由于ch只能容纳一个字符,因此系统将第一个字符“a”分配给ch。 示例 2: ;scanf("%5.1f",&a); 输入“1234”,没有出现错误信息,但a无法接收输入数据,a的值以随机数的形式输出。 如果您尝试输入其他数据,结果将是随机数。 用户原本打算使用这种scanf格式来输入一个宽度为5位、小数部分为1位的小数,但没有得到预期的结果。 因为,在scanf函数中,只有“字段宽度”(这里是5)附加的格式化字符(指定输入数据占用的列数),而没有附加“小数位数”的格式化字符(只有函数有它们),应该将其删除。 ".1",即scanf("%5f",&a); 或 scanf("%f",&a); 是可以接受的。 这时输入“123.4”即可接收。 因此,scanf函数中指定的格式字符及其附加格式描述字符应该被使用并且不能被滥用。 输入数据时无法指定精度。 例3:;scanf("%f",&x);输入“123.4”,x的输出值为随机数。 如果没有接收到输入数据,如果输入其他数据,结果将是一个随机数。 这是因为用户将x定义为双精度数据,当输入“%f”格式的数据时,无法接收。 相反,应该使用“%lf”或“%le”,即 scanf("%lf",&x); 这里输入“123.4”即可接收。
因此,长整型数据和双精度数据必须使用附加格式规范字符 l,短整型数据必须使用附加格式规范字符 h。 示例 4: inta,b;scanf("%2d,%*3d,%2d",&a,&b); 输入“12,345,67”。 此时,12被分配给a,67被分配给b。 注意:原则上“,%格式字符”的个数应等于“输入项”(&a,&b)的个数,一一对应。 然而,这里“%格式字符”的数量是3。 ,而输入数量为 2)。 因为scanf函数中多了一个格式描述字符“*”,加上“*”项就意味着输入数据没有赋值给对应的变量,所以跳过输入“345”,直接跳过下一个数据(“67”) ”) 被接收,导致““%格式字符”和“输入项”的个数可能不相等。在使用现成的一批数据时,有时有些数据是不需要的,可以使用此方法跳过例如,scanf("%c%c",&a,&b);("%c%c",a,b);输入A□B↙,输出A□',将A'赋予字符变量a',□' 字符变量b作为合法字符给定,此时切换到scanf("%c%*c%c",&a,&b);输入A□B↙,输出AB ,'A'给字符变量a',□'被%*c'跳过,B'给字符变量b。可见,在使用scanf函数时,必须在scanf指定的格式字符及其附加格式描述字符,既不能使用也不能滥用。
4、遇到空格、回车键、Tab键时注意输入结束标志①。 如果相邻两个格式指示符之间没有指定数据分隔符(如逗号、冒号等),则对应的两个输入数据应至少分隔一个空格,或者用Tab键分隔,或者输入一个数据,最后按在输入下一个数据之前先输入。 当以“%c”格式输入字符时,空格字符和“转义字符”均被输入为有效字符。 示例1:scanf("%d%d",&num1,&num2); 假设num1输入12,num2输入36,则正确的输入运算为:12□36↙或:12↙36↙示例2:scanf("%c%c%c",&c1,&c2,&c3);If从键盘输入a□b□c↙,将字符“a”分配给c1,将字符“□”分配给c2,将字符“b”分配给c3。 因为%c只需要读取一个字符,两个字符之间不需要用空格作为空格,所以把空格赋给c2作为下一个字符。
因此,应在输入字段的宽度结束时从键盘输入 abc↙②。 例如,“%3d”仅占用 3 列。 示例1:scanf("%3d",#1); 如果从键盘输入12345↙,则num1的值为123。 ③遇到非法输入。 例如,在输入数字数据时,遇到字母等非数字符号(数字符号仅由数字字符0-9、小数点和正负号组成)。 示例1:scanf("%d%c%f",&a,&b,&c); 如果输入.26↙,第一个数据对应的是%d格式输入1234后遇到的字母a,所以认为1234后面没有更多的数字,第一个数据到这里结束,1234被发送到变量A。 字符“a”被发送到变量b。 由于%c只需要输入一个字符,所以输入字符a后不需要添加空格,后续的值应该发送到变量c。 如果由于疏忽,将1230.26错误地输入为123o.26,并且由于123后面出现了字母“o”,则认为数值数据到此结束,将123赋予c。
5、注意scanf函数中输入项“格式控制”后面应该是变量地址,而不是变量名。 示例 1: intx;scanf("%d",&x); 该格式中,x前必须添加地址字符&,表示x的地址,即输入数据的位置。 例如写为 intx;scanf("%d",x ); 发生写入内存错误,并且 .exe 应用程序无法运行。 有些人经常在数组名前添加地址字符 & 。 示例 2:charc[10];scanf("%s",&c); 这也是错误的。 因为数组名代表了数组的起始地址,已经指出了输入数据的位置。 如果再次使用地址字符&,它就变成了辅助指针,具有完全不同的含义。 应改为charc[10]; scanf("%s",c) ; 因此,scanf函数中的“格式控制”只需要写成指针类型(一级指针)数据即可指出输入数据的位置。 不能生搬硬套,实际意义必须明确。