我对处理空格时scanf的行为感到困惑。
这是我正在使用的代码:
int main()
{
int val;
int c;
scanf("%d\t", &val);
c = getchar();
if(c == EOF)
printf("eof");
else if(c == '\t')
printf("tab");
else if(c == '\n')
printf("newline");
}
这是我传递的输入:
1234<tab><newline>
我希望这会打印“换行符”,因为scanf只查找制表符,而且假设scanf默认在缓冲区中留下空格。相反,它打印“eof”。 %d\t
似乎吞下了换行符。
我是否遗漏了有关scanf如何工作的内容?
请注意,如果我将其更改为以下内容,则会正确打印“换行符”:
int main()
{
int val;
int c;
scanf("%d", &val);
getchar(); /* note this extra getchar */
c = getchar();
if(c == EOF)
printf("eof");
else if(c == '\t')
printf("tab");
else if(c == '\n')
printf("newline");
}
答案 0 :(得分:3)
模式中的任何数量的空格(\t
)与输入中的任何空白量匹配(\t\n
)。
从手册页:
White space (such as blanks, tabs, or newlines) in the format string match any amount of white space, including none, in the input.
答案 1 :(得分:1)
你遇到了*scanf
should never be used:臭名昭着的空白处理的一个更臭名昭着的原因。您的'\t'
不仅匹配单个标签,而且匹配任何类型的空白,包括换行符!
假设你有getline
,做这种事情的最佳方法是这样的:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *line = 0;
char *p;
long val;
(void) getline(&line, 0, stdin);
val = strtol(line, &p, 10);
if (*p == '\0')
puts("eof (no tab)");
else {
if (*p != '\t')
printf("no tab, %c instead\n", *p);
p++;
if (*p == '\0')
puts("eof");
else if (*p == '\t')
puts("tab");
else if (*p == '\n')
puts("newline");
}
free(line);
return 0;
}
如果您没有getline
,fgets
通常就足够了。 (警告:不要将fgets
与gets
混淆。gets
是危险的,永远不应该使用,但fgets
只是在您希望程序在面对超长输入线。)
答案 2 :(得分:0)
“我在处理空格时对scanf的行为感到困惑。”是一个普遍的主张!
如果格式字符串中有任何空格,它将占用所有空格,因此“\ t”匹配任何空格字符串。