【问题标题】:Input/output problems输入/输出问题
【发布时间】:2012-06-15 01:32:04
【问题描述】:
#define MAX_COMMAND_LEN 32

char command[MAX_COMMAND_LEN];
while (1) {
    if (fgets(command, MAX_COMMAND_LEN, stdin) == NULL) {
        perror("Error: standard function fgets has failed\n");
        break;
    }

    if (command[strlen(command) -1] != '\n') {
        printf("Error: command length must be less than or equal to 30 characters\n");
        continue;
    }
    else {
         printf("Error: command not found\n");
    }

}
quit();

我有几个我无法处理的问题:

  1. 当我按下 Enter 时,它会停止循环并且不打印 command not found 消息。
  2. 当我输入大小超过 30 个字符的命令时,它会同时打印 command not foundcommand length must be less than or equal to 30 characters 消息。
  3. 当我输入 64 大小的命令时,它会打印两倍 30 长度的消息。

我相信它将输入分成30个长度的段并输入每个段,我该如何克服它?我试图刷新stdin,它不起作用。我想摆脱其余的输入。我该如何克服所有这些问题?

【问题讨论】:

  • 不要尝试刷新标准输入,它会调用 UB。

标签: c input flush


【解决方案1】:

对于问题 (i),抱歉,我不知道为什么,因为我的程序给出了正确的输出。

对于问题(ii),你给fgets的第二个参数是32,这个函数最多会读取32个字符,包括'\n'和'\0';剩下的仍然在标准输入缓冲区中,当您的程序在打印错误后继续执行时,fgets 将读取标准输入缓冲区中的剩余字符,直到它读取 '\n'。

如果你想刷新标准输入,你需要fpurge(stdin)函数来清除标准输入缓冲区。

【讨论】:

    【解决方案2】:

    对于您的第二个问题,这是因为 fgets 获取第 31 个(MAX_COMMAND_LEN,减去终止 '\0' 字符的空间)第一个字符,您注意到它不是换行符,并且下次循环 fgets 获取剩下的字符。

    【讨论】:

    • 实际上fgets 只获取了 31 个chars。它为'\0'保留空间。
    【解决方案3】:

    当我输入大小超过 30 个字符的命令时,它会同时显示“找不到命令”和“命令长度必须小于或等于 30 个字符”消息。

    fgets 最多读取MAX_COMMAND_LEN - 1 个字符,因为它为'\0' 留出了空间。
    这就是为什么对于任何超过 30 个字符的消息,fgets 读取的前 31 个字符不包含 '\n',因此会显示 30 个长度的消息。
    由于命令的第二部分末尾有一个'\n',所以command not found也被打印出来了。

    当我输入 64 大小的命令时,它会打印两倍 30 长度的消息。

    fgets 被此命令调用了 3 次。读取第一个 31 长度的块,然后读取第二个 31 长度的块,然后是剩余的字符。两个 31 长度的块都不包含 '\n' 字符,因此 30 长度的消息会显示两次。

    【讨论】:

      【解决方案4】:

      你可能误解了fgets实际上是works

      char * fgets ( char * str, int num, FILE * stream ); 从流中读取字符并将它们作为 C 字符串存储到 str 直到 (num-1) 个字符被读取或换行符或 到达文件结尾,以先到者为准。换行符 使 fgets 停止读取,但它被认为是有效字符并且 因此它包含在复制到 str 的字符串中。一个空 字符在读取字符后自动附加到 str 表示 C 字符串的结束。

      所以,

      1. 当您按“Enter”时 - 它会输入换行符,这在您的代码中不是例外情况。
      2. 当您输入大于 30 个字符的字符串时,fget 会多次读取它。
      3. 与 60 个字符相同 - 换行符不是字符串的最后一个字符,因此您会收到两次错误。

      【讨论】:

        猜你喜欢
        • 2012-02-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-04
        • 2013-12-15
        • 2020-06-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多