【问题标题】:fgets() getting skipped, how to clear user input?fgets() 被跳过,如何清除用户输入?
【发布时间】:2012-09-09 23:25:54
【问题描述】:

我使用 fgets() 获取用户输入,然后使用 sscanf() 将其解析为双精度。这是我的示例代码:

int menuItem = 0;
char input[3];
printf("Enter valid menu item"); //values are 1, 2, 3, 4, 5, and -1
fgets(input, sizeof input, stdin);
sscanf(input, "%d", &menuItem);

如果用户输入 3 位数字(无效输入,我想相应地处理),则会发生错误,它会通过自动将第三位数字作为下一个输入来跳过我的下一个 fgets()。例如,如果用户 inters 123,它现在将跳过下一个 fgets 并使用值 3 作为输入。我怎样才能清除这个,或者最多只能读取1位数字(但仍然能够处理-1)。

【问题讨论】:

    标签: c user-input fgets scanf


    【解决方案1】:

    你为什么不让你的输入数组更大呢?就像 50 字节...如果用户输入那么多,他们就是白痴,应该有奇怪的行为 =)

    这当然不优雅,但从长远来看,您可能没有在这里编写工业级代码。您只想修复一个愚蠢的错误,这是最简单的解决方案。

    [编辑]

    如果您对我为什么提出这个建议感到困惑。您的输入数组仅足以容纳 2 个值,外加一个空终止符。很明显,您希望它足够大,以确保用户输入了一个选项而不是两个选项

    【讨论】:

    • 好主意 - 我想你是对的,无论如何输入这么多数字都是罕见的。我想我很可能会按照你的建议做,但出于好奇,我将如何处理这样的错误呢?也就是说,假设我输入 [50],他们输入 80 个字符。我该怎么做才能从缓冲区中清除那些额外的,这样它们就不会自动放置在下一个 fgets() 中?
    • 因为fgets 将换行符视为有效字符,所以您可以在字符串中使用它。因此,您应该始终为您期望的字符、换行符和 NULL 终止符留出足够的空间。一旦你有了你的价值,就搜索\n。如果找不到,请再次致电fgets(并重复)。只有在读取了最大字符数时,您才应该这样做。这可能会在特殊情况下(例如 Ctrl-D)或其他过早的 EOF(如果读取文件或管道)导致问题。它还需要特别注意,因为换行符因操作系统而异。
    【解决方案2】:

    您的输入缓冲区允许 1 个数字、1 个换行符和 1 个终端 null '\0',这确实不够大。

    假设用户键入100 后跟一个换行符。第一次调用fgets() 将读取 2 位数字 (10),然后第二次调用将读取第三位数字和换行符;那么下一个调用将等待下一个输入。

    只需将缓冲区大小增加到更合理的值。对于我编写的许多程序,我使用 4096 的缓冲区大小。POSIX 标准将 _POSIX2_LINE_MAX 设置为 2048。如果您对此不满意,只需使用方便的数字,例如 64 或 128;你不会走得太远。

    您使用fgets()sscanf() 的技术绝对是更好的方向,但您应该检查sscanf() 是否解析了正确数量的值。 fgets() 加上sscanf() 的优点之一是您可以更好地报告用户输入的行中的错误;如果您直接使用fscanf()scanf(),这将不那么容易。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-06
      • 2021-11-29
      • 2016-04-26
      • 1970-01-01
      • 1970-01-01
      • 2020-08-17
      相关资源
      最近更新 更多