2017-06-04 54 views
-2

這是我的代碼與fgets()不按預期

int main(){ 
    int N,i,radius,diameter,count =0; 
    char str[20]; 
    char color[N][20]; 
    printf("Get the num : "); 
    scanf("%d",&N); 

    printf("Enter the mesage\n"); 
    for(i=0;i<N;i++){ 
     fgets(color[i],20,stdin); 
    } 
    for(i=0;i<N;i++){ 
     printf("%s",color[i]); 
    } 
    return 0; 
} 

由於輸入是:

N = 3 
red 50, 
50 green, 
blue 50 

這裏的問題是fgets在for循環中,如果N是3被執行,只有兩次。如果我評論scanf聲明,則不會出現此問題。有人可以解釋我是什麼導致這個問題,以及它如何解決?

+2

'的scanf( 「%d%* C」,&N);炭色[N] [20]; ' – BLUEPIXY

+0

讓我看看你給出的確切的三個輸入 –

+0

問題是你正在使用'scanf'作爲用戶輸入 – melpomene

回答

1

抓我的頭幾個小時後,我才意識到以下幾點:

  • 避免使用scanf函數。管理緩衝區溢出並不容易。
  • 總是嘗試使用fgets來獲取用戶輸入。

這裏嘗試此代碼:

#include<stdio.h> 
#include<stdlib.h> 
int main(){ 
    int N,i,radius,diameter,count =0; 
    char str[20]; 

    printf("Get the num : "); 

    char buffer[64]; 
    fgets(buffer, 64, stdin); 
    N = strtoul(buffer,NULL,10); 
    char color[N][20]; 

    printf("%d\n",sizeof(color)); 

    printf("Enter the mesage\n"); 

    for(i=0;i<N;i++){ 
     fgets(color[i],20,stdin); 
     if(color[i][strlen(color[i])-1]=='\n'){ 

    color[i][strlen(color[i])-1]='\0'; 
    } 
    else{ 

    while((getchar())!='\n');//this is just to prevent an overflow for the size of char arrays 
    } 

    } 
    for(i=0;i<N;i++){ 
     printf("%s\n",color[i]); 
    } 
    return 0; 
} 

注意,我第一輸入字符數組內的數。使用strtoul將其轉換爲數字(字符串爲無符號長整數)。現在在for循環中,我再次使用fgets進行輸入。問題是,如果輸入的字符串大於19個字符,則剩餘部分將留在輸入緩衝區內,並且應分配給後續輸入。爲了管理我在while循環中使用了getchar,它使用輸入流中的所有不必要的字符和換行符。避免使用fflush,因爲它可能會導致不確定的行爲在這裏得到解答

- fflush(stdin) function does not work

- http://www.geeksforgeeks.org/clearing-the-input-buffer-in-cc/

另外請注意,您使用的變長數組這可能並不總是一個不錯的選擇。較早版本的C編譯器禁止它們。在初始化N之前,您已經先聲明瞭顏色[N] [20]。這是錯誤的。

我建議你閱讀這也

- C - scanf() vs gets() vs fgets()

+1

'char color [N] [20];':您正在使用未初始化的變量。 – BLUEPIXY

+1

您正在使用'N'而不設置值。你應該防止'scanf(「%[^ \ n]」,color [i]);'''%[^ \ n]「'應該是'%19 [^ \ n]'' – BLUEPIXY

+1

''' – BetaRunner

-2

由於這種參考: https://www.tutorialspoint.com/c_standard_library/c_function_fgets.htm 這將是正確的:

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    int N, i, radius, diameter, count = 0; 
    char str[10]; 
    char color[20]; 
    printf("Get the num : "); 
    scanf_s("%d", &N); 

    printf("Enter the mesage\n"); 
    //for (i = 0; i<N; i++){ 
     fgets(color, 20, stdin); 
    //} 
    //for (i = 0; i<N; i++){ 
     printf("%s", color); 
    //} 
    return 0; 
} 

我改變scanfscanf_s爲VC++。

+0

你的代碼實際上是在做另一件事。 – BetaRunner

+0

確切地說,我的錯誤 – fardin

0

使用後scanf你需要清理緩衝區。我建議從不使用scanf的,只需使用與fgets然後將輸出轉換爲數字:

int main(){ 
    int N,i,radius,diameter,count =0; 
    char str[20]; 
    char color[N][20]; 
    printf("Get the num : "); 

    char buffer[64]; 
    fgets(buffer, 64, stdin); 
    N = atoi(buffer); // you need to include stdlib.h 

    printf("Enter the mesage\n"); 
    for(i=0;i<N;i++){ 
     fgets(color[i],20,stdin); 
    } 
    for(i=0;i<N;i++){ 
     printf("%s",color[i]); 
    } 
    return 0; 
} 
+0

並且在聲明'char color [N] [20]'之前,你必須確保'N'具有嚴格的正值(非零非負) - 當它不是未初始化。 –