2013-12-17 33 views
0

在我的C程序中,fgets沒有讀取任何數據。請看下面的代碼:奇怪的C代碼行爲(fgets函數)

#include <stdio.h> 
int main() 
{ 
     char string[50]; 
     int marks,i,n, limit; 
     printf("Enter Limit : \n"); 
     scanf("%d", &limit); 
     FILE *fptr; fptr=(fopen("string.txt","w")); 
     if(fptr==NULL){ 
       printf("Error!"); 
       return 0; 
     } 
     printf("Enter a string : \n"); 
     fgets(string, sizeof(string), stdin); 
     fwrite(string, 1, sizeof(string), fptr); 
     fclose(fptr); 
     return 0; 
} 

我進入限制後,程序將顯示「輸入一個字符串」,只是退出(輸入任何數據之前)。如果我刪除scanf("%d", &limit);聲明它工作正常。另外,如果在fgets以上添加getchar();聲明,它將正常工作。有人知道這個問題背後的原因嗎?

回答

4

這是因爲你用前面的代碼scanf的處理。當您輸入數字作爲輸入時,您按輸入鍵標記輸入的結尾,並在輸入緩衝區中添加換行符。 scanf所做的是讀取數字,但在輸入緩衝區中保留換行符(輸入鍵)。然後當你打電話給fgets時,它會看到這條單行換行並讀取它。

一個非常簡單的解決方案是由格式代碼後加一個空格告訴scanf跳過尾隨空白:

scanf("%d ", &limit); 
/*  ^  */ 
/*  |   */ 
/* Note space here */ 

如果以上方法無效,那麼你就可以讀取字符,直到你得到一個換行符:

int c; 
while ((c = fgetc(stdin)) != EOF && c != '\n') 
    ; 

此外,在Mac OSX上有可用於從inpu清除未讀數據的fpurge功能牛逼流:

fpurge(stdin); 

注:fpurge功能便攜。

在Linux和Windows上,您可以使用fflush來執行fpurge所做的同樣的事情,但請注意,它是允許它在Linux和Windows的庫中的擴展。根據C規範,在輸入流上調用fflush是未定義的行爲。見例如the Linux manual pageWindows reference page

+0

我改變了這樣的代碼。 scanf(「%d」,&limit);但現在輸出如下:1.輸入極限2. 3(註釋:輸入限制並按Enter鍵)3. sswew(註釋:我必須再次輸入此處並再次按Enter)4.輸入一個字符串(註釋:在輸入任何程序出口之前) – Vaquita

+1

我不知道爲什麼這不適合我。在'%d'後面給出額外的空間時,我必須按下額外的字符,這會使程序終止。 – haccks

+0

Joachim你能檢查一下嗎?我正在使用Mac OS X 10.8和CC Compiler。以上解決方案不適合我。 – Vaquita

0

如果使用sscanf並輸入號碼,你打「回車」 ......數由sscanf處理,但「確認」是由fgets

0

這是因爲fgets讀取前一個scanf左側的換行符\n\n吃完這個可能的方法在scanf之後加getchar

getchar(); 
    printf("Enter a string : \n"); 
    fgets(string, sizeof(string), stdin);