2014-01-21 90 views
-2

對於我的實踐任務,我必須使用gets()或fgets()。 我選擇fgets()作爲它的更安全。fgets()不忽略新行

第一個輸入是爲了能夠保存最多5個字符。 所以我給了字符數組的大小6以適應尾隨'\ 0'。

我發現與fgets(),它的問題將末尾的「\ n」,當你按下Enter鍵(使用與fgets()標準輸入)

我做了一些調查,發現了一個for循環,試圖擺脫它。然而,它似乎沒有工作,我不能爲我的生活弄清楚爲什麼。

當我輸入5個字符時,仍然跳過下一個輸入。

下面是代碼:

#include <stdio.h> 
#include <string.h> 

int main(void) 
{ 
    //Declare char arrays 
    char arcInputString5[6]; 
    char arcInputString10[11]; 
    char arcInputString15[16]; 
    char arcInputString20[21]; 
    int  clean1, clean2, clean3, clean4; 
// int  nStrLen1, nStrLen2, nStrLen3, nStrLen4; 
// nStrLen1 = nStrLen2 = nStrLen3 = nStrLen4 = 0; 

printf("\nPlease Input String 1 - Max Length 5: "); 
//gets(arcInputString5); 
fgets(arcInputString5, 6, stdin); 

for(clean1 = 0; clean1 < strlen(arcInputString5); clean1++) 
{ 
    if(arcInputString5[clean1] == '\n' || arcInputString5[clean1] == '\r') 
    { 
     arcInputString5[clean1] = '\0'; 
     break; 
    } 
} 

printf("\nPlease Input String 2 - Max Length 10: "); 
//gets(arcInputString10); 
fgets(arcInputString10, 10, stdin); 

printf("\nPlease Input String 3 - Max Length 15: "); 
//gets(arcInputString15); 
fgets(arcInputString15, 15, stdin); 

printf("\nPlease Input String 4 - Max Length 20: "); 
//gets(arcInputString20); 
fgets(arcInputString20, 20, stdin); 

printf("\nThankyou For Your Inputs - They Are Shown Back To You Below\n"); 

puts(arcInputString5); 
puts(arcInputString10); 
puts(arcInputString15); 
puts(arcInputString20); 

printf("\nThe String Lengths For Each Input Are Listed Below"); 

printf("\n%d", strlen(arcInputString5)); 
printf("\n%d", strlen(arcInputString10)); 
printf("\n%d", strlen(arcInputString15)); 
printf("\n%d", strlen(arcInputString20)); 

}

伊夫試圖這樣做的for循環的多種方式實現,例如使用數字6代替 「strlen的(arcInputString5)」

任何幫助將不勝感激。

編輯:

示例性輸入:

asd d 

輸出示例:

Please Input String 2 - Max Length 10: //skips this 
Please Input String 3 - Max Length 15: //this is the next line for input 
+0

請顯示程序的確切示例輸入和輸出。 –

+1

與「不刪除換行符」不同的是「添加換行符」。 Enter鍵提供一個換行符; 'gets()'函數會將它從返回的字符串中移除,但是'fgets()'不會 - 這至少會讓您有機會檢測您是否有完整的行或輸入行是否由於空間不足而被截斷。 –

+2

一般來說,不要將輸入限制爲5個字符;允許(爲了參數)256個字符的輸入,然後檢查用戶沒有輸入超過5個字符(除了換行符)。這在很大程度上避免了必須清理超長字符串中的額外數據的問題。實際上,我會使用4096作爲輸入的默認長度(而不僅僅是256),但選擇任何足夠大的值都不會出現問題。 –

回答

2

fgets()讀取一個字符比從stdin給定的緩衝區大小小於然後 附加一個NUL -字符。因此,對於您的情況,使用6個字符的輸入緩衝區, 它將0123d中的「asd d」讀取,並且終止行輸入的換行符仍然未讀。

然後下一個fgets()(只)將這個換行符讀入arcInputString10

您需要一個緩衝區大小(至少)7才能讀取包含來自stdin的 換行符的五個字符「asd d」。

這同樣適用於您用於fgets()的其他緩衝區。

加了:作爲喬納森萊弗勒正確地評價,一個較好的方法是提供 「大」輸入緩衝器fgets()和 讀取一行後檢查用戶輸入的實際長度。

您還應該注意,如果 (文件結束)無法讀取任何字符,則fgets()將返回NULL,因此您應該檢查返回值。

+0

同意,但請注意,如果用戶錯誤地使用了ant類型'supercalifragilisticexpialidocious'而不是'超級',那麼代碼必須從超長輸入中恢復。用戶會犯這樣的錯誤。 –

+0

@JonathanLeffler:你是完全正確的,我的回答只解釋了*爲什麼*它沒有按預期工作。您的評論http://stackoverflow.com/questions/21270323/fgets-not-ignoring-new-line/21270524?noredirect=1#comment32049166_21270323的問題描述了更好的解決方案。 –

+0

謝謝Martin給出了一個明確的解釋。它幫助了很多。 –

0

調用getchar()以在請求下一個用戶輸入之前從輸入流檢索換行符。

我喜歡用簡單的函數來清除輸入流

void clear() { 
    while(getchar() != '\n'); 
} 
1

變化到:
arcInputString5[7];
fgets(arcInputString5, 7, stdin);

您需要給予空間'\ n'和'\ 0'字符。

valter