【问题标题】: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 found 和 command 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
        相关资源
        最近更新 更多