【问题标题】:Why does scanf ask twice for input when there's a newline at the end of the format string?当格式字符串末尾有换行符时,为什么 scanf 会要求输入两次?
【发布时间】:2013-03-22 07:48:50
【问题描述】:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *method1(void)
{
    static char a[4];
    scanf("%s\n", a);
    return a;
}

int main(void)
{
    char *h = method1();
    printf("%s\n", h);
    return 0;
}

当我运行上面的代码时,提示要求我两次 输入(我只在代码中使用scanf 一次)。这是为什么呢?

(我输入了“jo”;它要求更多输入,所以我再次输入了“jo”。然后它只打印了一次“jo”。)

【问题讨论】:

  • 你得到了什么输出?
  • 这是一个非常短的数组。您输入的数据是否过多?
  • 我输入 jo。它要求另一个输入。然后我再次输入 jo。然后只打印一次 jo。
  • 我知道这只是一个sn-p,但你应该始终检查scanf和friends等转换函数的结果。

标签: c scanf


【解决方案1】:

来自我的 scanf 手册页

格式字符串中的空白(例如空格、制表符或换行符)与输入中的任意数量的空白匹配,包括无空白。其他一切都只匹配自己。

因此,scanf ("%s\n", a) 将扫描一个字符串,后跟可选的空格。由于在第一个换行符之后可能会出现更多空白,因此 scanf 不会在第一个换行符之后完成,而是查看接下来的内容。您会注意到您可以输入任意数量的换行符(或制表符或空格),而 scanf 仍会等待更多。

但是,当您输入第二个字符串时,空格序列被定界并且扫描停止。

使用scanf ("%s", a) 不扫描尾随空格。

【讨论】:

    【解决方案2】:

    您必须从scanf 的字符串格式中删除\n。应该是

    scanf("%s",a);
    

    编辑:解释

    %s 表示 scanf 读取输入字符,直到它获得一个分隔符,该分隔符应该是空格,例如空格或制表符或换行符(\n),因此第一个输入是作为 @ 的分隔符987654326@ 并将"\n" 添加到字符串格式"%s\n" 意味着scanf 将等待2 个换行符第一个换行符与"%s" 的分隔符有关,第二个换行符与字符串的\n 有关格式。

    【讨论】:

    • 您在正确的轨道上,但您并没有说scanf 将继续读取空格,直到遇到非空格字符。在输入非空格并停止scanf 之前,您可以输入许多新行(以及空白或制表符)。与scanf() 的文件I/O 变体相比,更喜欢fgets()sscanf() 的另一个原因。
    • 您关于 scanf 等待两个换行符的推理是错误的。所有输入的换行符(甚至超过两个)都被 single \n 格式扫描,任何混合的空格和制表符也是如此。请阅读 C 标准或手册页中的 scanf 规范。
    【解决方案3】:

    使用 gets() 或 fgets() 代替...或者使用 scanf("%[^\n]s",a);

    【讨论】:

    • scanf 输入到数组中,直到它收到一个空格..所以使用 %[^\n]s...或者不要使用 scanf,而是使用 fgets() 或 gets()跨度>
    • "%[^\n]s" 由两个指令组成:%[^\n],它要么匹配(并存储)一个或多个非'\n'字符,要么因为立即遇到'\n'而失败, 和 s 匹配文字's'并丢弃它,或者失败并将非's'字符推回标准输入。第一个指令将连续尝试失败,因为 '\n' 不是 's',所以 '\n' 将被直接推回标准输入,这是遇到的第一个字符。自己看:char a[64]; int n = scanf("%[^\n]s", a); assert(n == 1); n = scanf("%[^\n]s", a); assert(n == 1);
    • 我的建议是阅读fscanf 手册,以便您消除对%[ 指令和%s 指令的混淆。
    【解决方案4】:

    从 scanf 格式中删除 \n 并给出一个输入,它会根据给定的输出显示一次输出。

    【讨论】:

    • 斜线错误。此外,此答案与之前的答案没有任何区别。
    【解决方案5】:

    您可以使用其中任何一种来避免上述问题: scanf("%s",a); 要么 scanf("\n%s",a);

    【讨论】:

      【解决方案6】:

      试试这个:不要在scanf上使用\n,它不会问你两次,有时它可能会显示错误

      您的代码scanf("%s\n", a);

      在 scanf 上试试这个scanf("%s", a);

      【讨论】:

      • 其他答案在 8 年前就说明了这一点。这并没有增加任何新内容。
      【解决方案7】:

      不要在 scanf stdio 函数中使用转义序列

           scanf ("%s", a);
      

      【讨论】:

      • 没有解释为什么 - 以及当你这样做时会发生什么。这对MOHAMEDanswer 或接受的答案没有任何帮助。
      猜你喜欢
      • 2021-07-23
      • 2014-08-06
      • 2020-07-15
      相关资源
      最近更新 更多