【问题标题】:scanf without additional arguments in C在 C 中没有附加参数的 scanf
【发布时间】:2016-02-11 17:50:00
【问题描述】:

是否允许使用scanf(" ") 而不使用其他参数来忽略初始空格?
我正在使用getchar() 来读取单词的字符,并且我想忽略单词之前的空格(之后的空格用于检查单词的结尾)。
代码如下,对吗?

char *read_word() {
    int size = 2;
    int char_count = 0;
    char *s;
    char ch;

    s = mem_alloc(size);

    scanf(" ");

    while ((ch = getchar()) != EOF) {
        if (char_count >= size) {
            s = mem_realloc(s, size++);
        }

        if (ch == ' ' || ch == '\n') {
            s[char_count] = '\0';
            break;
        }

        s[char_count++] = ch;
    }

    return s;
}

【问题讨论】:

  • 绝对.....
  • 旁白:mem_realloc(s, size++); --> mem_realloc(s, ++size);
  • @raxell 如果出现EOF,则s[char_count] = '\0'; 不会出现。
  • @WeatherVane 我听说过答案无效(在代码审查中),但不是……评论无效?如果错误与问题无关,为什么重要?
  • @Insane 是的。评论旨在要求对帖子进行澄清;它们一直过时(并被标记为过时)。

标签: c scanf


【解决方案1】:

scanf()函数的定义(*),强调我的:

格式由零个或多个指令组成:一个或多个空白字符、一个普通的多字节字符(既不是%也不是空白字符)、或 转换规范。

[...]

由空白字符组成的指令通过读取输入直到第一个非空白字符(仍然未读取)或直到无法读取更多字符来执行。

所以scanf( " " ); 完全有效。


(*):ISO/IEC 9899:1999, 7.19.6.2 fscanf 函数,第 3 节和第 5 节。

其他*scanf 函数根据本节定义。

【讨论】:

    【解决方案2】:

    要补充其他答案,以下所有内容均有效:

    scanf(" ");      // skip over whitespace
    scanf("xyz");    // skip over the longest leading substring of "xyz" if present
                     // i.e. "xyz" or "xy" or "x"
    scanf(" %*s ");  // skip over the first string and whitespace around it
    

    【讨论】:

    • 感谢您使用原始答案添加更多知识 - 有帮助
    【解决方案3】:

    manpage 说:

    格式字符串由一系列指令组成

    ...

    指令是以下之一:

    • 一系列空白字符(空格、制表符、换行符等;请参阅 空间(3))。该指令匹配任意数量的空白, 包括无,在输入中。

    ...

    所以是的,scanf 的使用是合法的。


    如果你追求效率:

    int c;
    while(isspace(c=getchar()) {;}
    

    导致一条更有效的路径,如 getchar 等。人。往往有_unlocked 对应物,不像scanf

    【讨论】:

    • 虽然在这种情况下不是问题,但我会小心依赖联机帮助页。他们通常不会清楚地区分什么是 ISO C 和什么是 POSIX——而这 可以 有所作为。因此,如果问题是关于“在 C 中”是否合法,标准胜过手册页。 (我并不是因为我引用了它,而是因为我不时在非 POSIX 平台上工作。)
    • @DevSolar 我同意。我们几乎同时发布。如果我第一次看到你的,我可能不会发布我的,但我认为我的仍然有一些价值(=我从中获得积分:D)所以我会保留它。
    • 请注意,要使您的getchar 示例等效于scanf(" "),您必须在末尾添加ungetc(c, stdin)
    【解决方案4】:

    我会尝试:

    int skip = -1;
    if (scanf(" %n", &skip)>=0 && skip>0)   {
      // you have skipped skip spaces
    }
    

    >=0 测试检查 scanf 没有失败(例如,因为标准输入上的 EOF 或输入错误)。 skip>0 测试检查我们是否跳过了至少一个类似空格的字节。 %n 转换说明符给出解析的字节数。

    【讨论】:

    • >=0test 看起来不需要。它有什么帮助?
    • 我在想如果标准输入上有 EOF 或输入错误,skip 就无法更改,因此skip 将保留其 -1 值,然后 skip >0 测试失败。 IAC,检查scanf() 的返回值是值得鼓励的。
    • 好吧,如果没有跳过空格,我的测试就失败了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-22
    • 1970-01-01
    • 1970-01-01
    • 2015-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多