2012-06-12 91 views
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. 当我按下回车,它停止循环,不打印command not found消息。
  2. 当我输入一个大于30个字符的命令时,它将输出command not foundcommand length must be less than or equal to 30 characters消息。
  3. 当我输入一个64尺寸的命令时,它打印两次30长度的信息。

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

+3

不要尝试刷新stdin,它会调用UB。 – SuperSaiyan

回答

2

关于第二个问题,这是因为fgets取31(MAX_COMMAND_LEN,减去终止'\0'字符空格)前几个字符,你发现它只有一行和周围的环fgets下一次获取剩余的字符。

+1

实际上'fgets'只能提取31个字符。它保留了''\ 0''的空间。 –

+0

@EitanT谢谢,更新的答案。 –

1

你可能误解了如何fgets实际上works

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

所以,

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

对于问题(i),抱歉,我不知道为什么,因为我的程序给出了正确的输出。对于问题(ii),你给出fgets的第二个参数是32,该函数将读取至多32个字符,包括'\ n'和'\ 0';剩下的东西仍然在stdin缓冲区中,当你的程序在打印错误后继续运行时,fgets将读取stdin缓冲区中的剩余字符,直到它读入'\ n'。

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

2

当我输入一个大于30个字符的命令时,它会同时打印'command not found'命令和'命令长度必须小于或等于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长度的消息显示两次。