[英]scanf buffering with tabs and newlines
我在处理空格时对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");
}
模式中的任何数量的空格( \\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.
你遇到了一个更为臭名昭着的原因,就是为什么永远不要使用*scanf
:令人困惑的空白处理。 你的'\\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
如果你希望你的程序是在超长输入线,面对强大的仅仅是不便。)
“处理空格时,我对scanf的行为感到困惑。” 是普遍的主张!
如果格式字符串中有任何空格,它将消耗所有空格,因此“\\ t”匹配任何空格字符串。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.