2012-06-12 90 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長度的消息顯示兩次。