Here,我在接受的答案中看到了这句话:
大多数转换说明符都会跳过包含换行符的前导空格,但
%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'
将被第二个{{1}消耗与scanf
。我在linux和windows上测试了gcc,行为是一样的:
gcc(GCC)4.7.2 20120921(Red Hat 4.7.2-2)
版权所有(C)2012 Free Software Foundation,Inc。
这是免费软件;查看复制条件的来源。没有 保证;甚至不适用于适销性或特定用途的适用性。
所以我的问题是:%c
和%d
为什么表现不同w.r.t. %c
中的'\n'
?
答案 0 :(得分:12)
这是一贯的行为,你只是想错了。 ;)
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'
。
答案 1 :(得分:10)
7.21.6.2 fscanf函数
...
5由白色空格字符组成的指令通过读取输入来执行 第一个非空白字符(仍未读取),或直到没有其他字符可以 被阅读。指令永远不会失败 ...
7作为转换规范的指令定义了一组匹配的输入序列,如 下面针对每个具体说明。转换规范按以下步骤执行:
8跳过输入的空格字符(由isspace
函数指定),除非 规范包括[
,c
或n
指定者。 284)
9除非规范包含n
指定符,否则将从流中读取输入项。 <强>一种 输入项被定义为不超过的最长输入字符序列 任何指定的字段宽度,它是匹配输入序列的前缀,或者是匹配输入序列的前缀。 285) 输入项目之后的第一个字符(如果有)仍未读取。如果输入的长度 item为零,指令的执行失败;这种情况是匹配失败,除非 文件结束,编码错误或读取错误阻止了流的输入,其中 这是一个输入失败的情况。
284)这些空白字符不计入指定的字段宽度 285)fscanf将最多一个输入字符推回到输入流上。因此,有些序列 strtod,strtol等可接受的,对fscanf来说是不可接受的。
我强调的重点。
空格不是有效整数字符串的一部分,因此%d
转换说明符跳过任何前导空格是有意义的。但是,空格本身可能是有效的,因此%c
转换说明符不跳过它是有意义的。
上面的第5条,如果在%c
指令之前的格式字符串中放置一个空格,将跳过所有前导空格:
scanf(" %c", &ch);
答案 2 :(得分:2)
这是因为空格永远不能是整数,但空格是由字符组成的。如果你特别想要一个角色尝试类似
scanf("%c", &ch );
while(isspace(c))
scanf("%c" , &ch);
如果您只想使用字母和数字,请使用!isalnum()
,或仅使用!isalpha()
字母。
答案 3 :(得分:-2)
我不是专家,但我发现这样做:
fflush(stdin);
每次扫描后都有帮助..
如:
scanf("%c", &ch);
fflush(stdin);