2.3 输入的格式配对错误

【例2.3】下面的程序不能正常运行,是何原因?


#include <stdio.h>
void main
( 
)
{
      double x
,y
;
      printf
( "
输入x
和y
的值:"
);
      scanf
( "%f%f"
,&x
,&y
);
      printf
( "%g+%g=%g\n"
,x
,y
,x+y
);
}
  

运行示范如下。


输入x
和y
的值:
2.1 3.4
-9.25596e+061+-9.25596e+061=-1.85119e+062
  

有人可能认为是printf语句的问题,其实不是,g格式符用来输出实数,它根据数值的大小自动选f格式或e格式。输出double(包括long double)格式的数据不需要使用lf,所以这个格式是正确的。

经过分析,只能认为是scanf的格式不对了。f是输入实数(浮点数),输入数据可以用小数形式或指数形式。e与f作用相同并可以互相替换,所以只能去看lf格式了。

“l”格式用于输入长整型数据,说明相应的参数是long型,而不是int型。读入float数据时,说明相应的参数应是double型。由此可以得出结论:是格式不匹配造成的错误,应将格式符改为“lf”或者将声明改为“float”型。将scanf语句改为


scanf
("%lf%lf"
,&x
,&y
);
  

则得到正确的演示输出结果为“2.1+3.4=5.5”。这种改动对将声明改为


long double x
,y
;
  

也是正确的。如果不改变scanf语句,可以将声明改为


float x
,y
;
  

需要注意的是,这时scanf虽然不能使用“lf”格式,但可以使用e格式,即


scanf
("%e%e"
,&x
,&y
);
  

当然,这种情况也支持g格式,即


scanf
("%g%g"
,&x
,&y
);
  

注意它们只对float声明的变量有效,对使用double格式声明的变量无效。

【例2.4】下面程序错在哪里?分析分别输入123456789和123 456 789时的输出结果。


#include <stdio.h>
void main
( 
)
{
     int a=9
,b=5
,c=0
;
     char c='A'
;
     printf
("
输入:"
);
     scanf
("%2d%*3d%d%c"
,&a
,&b
,&c
);
     printf
("
输出:a=%g
,b=%g
,c=%c\n"
,a
,b
,c
);
}
  

错在混淆了整数和浮点数的格式,g对整数无效。应该改为


printf
("
输出:a=%d
,b=%d
,c=%c\n"
,a
,b
,c
);
  

输入语句中的“*”号表示本输入项在读入数据后不赋给相应的变量。%2d用来指定数据位数的宽度为2。如输入123456789,则对应于%2d的格式是把数据前面的12存入变量a中;%*3d表示输入3位数,但不赋给任何变量,即不使用数据345;后面的格式是%d,它没有数字域,所以将6789赋给b。因为后面是换行符,所以c存入的是换行符。如果c是使用%d输出,则输出“c=10”。但这里是使用%c,换行符不是可显示字符,所以运行结果为


输入:
123456789
输出:a=12
,b=6789
,c=
  

需要注意的是,如将这条语句改为


scanf
("%2d%*3d%1d%c"
,&a
,&b
,&c
);
  

则输出演示的结果为


输出:a=12
,b=6
,c=7
  

虽然%1d是使b只取1位数字(即数字6),但b不用的数据(789)仍然能供后面使用。因为这是一组输入,%*只是修饰舍掉的位数,后面的%1d格式是取舍给变量的格式,剩下数据789,c是单字符型而不是字符串,所以只能取数据7。

回到原来的程序,当输入123 456 789时,结果又不一样。它将12赋给a,丢弃3,但3之后是空格,编译系统认为这个字符串已经结束,就把下面的字符串456赋给b,虽然有789的输入,但它们与456之间有一个空格,所以是用这个空格为c赋值,输出演示的结果为


输入:
123 456 789
输出:a=12
,b=456
,c=
  

被舍弃的字符串是以空格区分的,如果数量不够,也只舍弃到空格为止。如果数量足够,则取舍到规定数量,将剩下的赋给变量。例如:


输入:
1 2 3456 789
输出:a=1
,b=3456
,c=
输入:
1 23456 789
输出:a=1
,b=56
,c=
  

如果用%d输出c,则c=32。如果想让789赋给c,则要将c定义为字符串。

【例2.5】使用字符串的例子。


#include <stdio.h>
void main
( 
)
{
     int a=9
,b=5
; char c[4]
;
     printf
("
输入:"
);
     scanf
("%2d%*3d%d%s"
,&a
,&b
,&c
);
     printf
("
输出:a=%d
,b=%d
,c=%s\n"
,a
,b
,c
);
}
  

运行实例如下。


输入:
123 456 789
输出:a=12
,b=456
,c=789
  

《C语言解惑》