在这里 ,我看到了在接受的答案这样的说法:
大部分的转换说明跳过前导空白包括换行,但%c
没有。
对我来说,没有在本不同的行为清楚的理由,我本来期望统一的一个(例如总是跳过或从不)。
我到了这样的问题,采用了一块C代码是这样的:
#include "stdio.h"
int main(void){
char ch;
int actualNum;
printf("Insert a number: ");
scanf("%d", &actualNum);
// getchar();
printf("Insert a character: ");
scanf("%c", &ch);
return 0;
}
交换两个scanf
小号解决了问题,以及在(注释) getchar
,否则'\n'
第一插入的将由第二被消耗scanf
与%c
。 我在GCC都在Linux和Windows测试,该行为是相同的:
海湾合作委员会(GCC)4.7.2 20120921(红帽4.7.2-2)
版权所有(C)2012自由软件基金会。
这是自由软件; 看到复印条件源。 有没有保修; 甚至不是针对特定目的的适销。
所以我的问题是:为什么%d
和%c
行为不同WRT '\n'
在scanf
?
从马的嘴 :
7.21.6.2 fscanf函数
...
5的空白字符(一个或多个)构成的指令是通过读取输入到第一个非空白字符(这仍然是未读)执行,或直到没有更多的字符可被读取。 该指令永远不会失败。
...
7.一种指令,该指令是转换SPECI音响阳离子德连接定义了一个组匹配的输入序列,如下面对于每个SPECI音响ER描述的。 A转换SPECI音响阳离子在下面的步骤执行:
8输入的空白字符(如由编SPECI音响isspace
函数)被跳过, 除非SPECI音响阳离子包括[
, c
,或n
SPECI音响ER。 284)
9.一种输入项目是从该流读取,除非SPECI音响阳离子包括n
SPECI音响ER。 的输入项被解音响定义为不超过任何SPECI音响编音响场宽度并且是或的预连接的x,一个匹配的输入序列的输入字符的最长序列。 285)的第一个字符,如果有的话,在输入项保持未读。 如果输入项的长度是零,则该指令的执行失败; 该条件匹配的失败,除非最终OF-音响文件,编码错误,或读出错误从流,在这种情况下它是一个输入故障防止输入。
284)这些空白字符不被计数针对一个特定的编音响场宽度。
285)的fscanf推回至多一个输入字符到的输入流。 因此,一些这样的序列是可以接受的的strtod,strtol将等等,都是不能接受的fscanf。
由我添加的重点。
空白是不是一个有效的整数字符串的一部分,因此是很有意义的%d
转换符跳过任何前导空格。 不过,空白可能是对自己有效,因此是很有意义的%c
转换符不跳过它。
按照上述第5,如果你把一个空格在之前的格式字符串%c
指令,所有领先的空白将被忽略:
scanf(" %c", &ch);
这是一致的行为,你只是想错了。 ;)
scanf("%c", some_char); // reads a character from the key board.
scanf("%d", some_int); // reads an integer from the key board.
所以,如果我这样做:
printf("Insert a character: ");
scanf("%c", &ch); // if I enter 'f'. Really I entered 'f' + '\n'
// scanf read the first char and left the '\n'
printf("Insert a number: ");
scanf("%d", &actualNum); // Now scan if is looking for an int, it sees the '\n'
// still, but that's not an int so it waits for the
// the next input from stdin
这不是它的消耗在这种情况下对自己的换行符。 试试这个:
char ch;
char ch2;
printf("Insert a character: ");
scanf("%c", &ch);
printf("Insert another character: ");
scanf("%c", &ch2);
它会“跳过”第二个scanf()
,因为它在读取'\n'
在那个时候。 scanf()
是一致的,你必须消耗的是'\n'
如果你要正确地使用它。
这是因为空格不可能是整数,但空格是由字符组成。 如果你特别想要一个字符尝试类似
scanf("%c", &ch );
while(isspace(c))
scanf("%c" , &ch);
或者使用!isalnum()
如果你希望只允许字母和数字或!isalpha()
只字母。
我不是专家,但我发现,这样做:
fflush(stdin);
以后每scanf的帮助..
如:
scanf("%c", &ch);
fflush(stdin);