1、scanf()问题
(1)对于%d
scanf会跳过空白字符,遇到第一个数字字符或一个符号(+或-)才开始读取;
如果遇到一个非数字字符,便认为读到整数的末尾,然后把非数字字符放回输入。这意味着下次读取输入时,首先读到上次读取丢弃的非数字字符。
如果第一个非空白字符是A而不是数字,scanf将停在那里,并把A放回输入中,不会把值赋给变量,程序在下一次读取输入时,就一直无法越过A读取下一个字符。(C规定在第一个出错处停止读取输入)
scanf("%d,%d",&n,&m);
printf("%d/%d",n,m);
以下输入等价
88,121
88, 121
88,
121
88,121
88, 121
//但是输入
88 ,121或
88 ,121
//运行结果为
88/-1217134604
...
scanf("%d ,%d",&n,&m);
格式字符串中的空白意味着跳过下一次输入项前面的所有空白。
以下输入等价
88,121
88 ,121
88 , 121
scanf("%d%d",&n,&m);与scanf("%d %d",&n,&m);等价scanf("%d",&n,&m);与scanf(" %d",&n,&m);等价
scanf("%d %d",&n,&m);
printf("%d%d\n",n,m);
//输入
10 40
//输入
1040
while(1)
{
printf("请输入:");
scanf("%d",&a);
printf("%d\n",a);
}
//运行结果
请输入:20
20
请输入: 20
20
请输入:30 //后面后空格
30
请输入:50
50
请输入:c
50
请输入:50
请输入:50
请输入:50
请输入:50
请输入:50
请输入:50
...
解决方法
while(1)
{
printf("请输入:");
scanf("%d",&a);
printf("%d\n",a);
while(getchar() != '\n'); //清空输入缓冲
}
getchar由宏实现:#define getchar() getc(stdin)。getchar有一个int型的返回值。当程序调用getchar时,程序就等着用户按键。用户输入的字符被存放在键盘缓冲区中,直到用户按回车为止(回车字符也放在缓冲区中)。当用户键入回车之后,getchar才开始从stdin流中每次读入一个字符。
getchar函数的返回值是用户输入的第一个字符的ASCII码,如出错返回-1,且将用户输入的字符回显到屏幕。
如果用户在按回车之前输入了不止一个字符,其他字符会保留在键盘缓存区中,等待后续getchar调用读取。也就是说,后续getchar调用不会等待用户按键,而直接读取缓冲区中的字符,直到缓冲区中的字符读完为后,才等待用户按键。
(2)对于%s
scanf()会读取除空白以外的所有字符。
scanf()跳过空白开始读取第一个非空白字符直到再次遇到空白。
注意:当scanf()把字符串放进指定数组中时,它会在字符序列的末尾加上’\0’,让数组中的内容成为一个字符串。
char arr[10];
scanf("%s",arr); //与scanf(" %s",arr);的行为相同
//以下输入等价
string
string
sting
//输出都是
string
scanf("%s\n",arr);
//输入string再换行时无法结束
(3)对于%c
除了%c,其他转化说明都会自动跳过待输入值前面所有的空白。
scanf("%c",&ch); //从输入中的第1个字符开始读取
//输入
h
//输出
h
//输入
h
//输出
scanf(" %c",&ch); //从第1个非空字符开始读取
//输入
h
//输出
h
//输入
h
//输出
h