繁体   English   中英

使用制表符和换行符进行scanf缓冲

[英]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;
}

如果你没有getlinefgets通常就足够了。 (警告:不要混淆fgetsgetsgets是危险的,不应该被使用,但fgets如果你希望你的程序是在超长输入线,面对强大的仅仅是不便。)

“处理空格时,我对scanf的行为感到困惑。” 是普遍的主张!

如果格式字符串中有任何空格,它将消耗所有空格,因此“\\ t”匹配任何空格字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM