0
#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 个字符的命令时,它会同时打印 thecommand not foundcommand length must be less than or equal to 30 characters消息。
  3. 当我输入一个 64 大小的命令时,它会打印两倍 30 长度的消息。

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

4

4 回答 4

2

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

于 2012-06-12T07:34:59.057 回答
2

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

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

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

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

于 2012-06-12T08:01:23.910 回答
1

您可能误解了fgets实际的工作原理

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

所以,

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

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

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

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

于 2012-06-12T07:49:50.097 回答