2013-10-08 99 views
0

看來我的fgets()的實現在這裏是不正確的,非常感謝一些額外的眼睛來看看我所做的!fgets在C中導致無限循環

下面的代碼

int main(int argc, const char* argv[]){ 
    int numIntegers; 
    char buffer[20]; 
    int intArray[10]; 
    //if no argument is passed in, terminate 
    if (argc == 1){ 
      printf("no argument given, terminating..\n"); 
      return EXIT_FAILURE; 
    } 
    else{ 
      numIntegers = atoi(argv[1]); 
      //we only want numbers greater than 0 
      if (numIntegers <= 0){ 
        printf("# must be greater than 0\n"); 
        return EXIT_FAILURE; 
      } 
      else{ 
        printf("Enter %d integer values to place in array: \n", numIntegers); 
        for (int i = 0; i < numIntegers; i++){ 
          fgets(buffer, numIntegers, stdin); 
          intArray[i] = atoi(buffer); 
          printf("Index is = %d \n", i); 
        } 
      } 
    } 

    //for (int i =0; i < numIntegers; i++){ 
    //  printf("Index[%d] = %d \n", i, intArray[i]); 
    //} 
} 

這裏的輸出,與除的整數沒有其它文本行是用戶輸入。注意我的價值是如何重置的。只有當我給出超過10的任何初始參數時纔會出現此問題。無論出於何種原因,它都會將for循環變成無限循環。

$ ./a.out 11 
Enter 11 integer values to place in array: 
5 
Index is = 0 
2 
Index is = 1 
1 
Index is = 2 
2 
Index is = 3 
3 
Index is = 4 
4 
Index is = 5 
123 
Index is = 6 
123 
Index is = 7 
123 
Index is = 8 
1 
Index is = 9 
2 
Index is = 2 
2 
Index is = 3 
3 
Index is = 4 
5 
Index is = 5 
1 
Index is = 6 
12 
Index is = 7 
+0

這是一個相當本地化的問題,但解釋發生了什麼(超出標準的「檢查你的界限」建議)是一種很酷的方式。請務必閱讀我的答案的結尾。 – Floris

回答

2

您正在使用

fgets(buffer, numIntegers, stdin); 

第二個參數應該是緩衝區的大小 - 在你的情況,20即至少一個明顯的問題......

下問題:您允許numIntegers大於10 - 因此您將在intArray的末尾寫入數值。要解決這個問題太...

if(numIntegers > 10) { 
    printf("cannot have number greater than 10!\n"); 
    // abort, retry, ignore... 
} 

其實 - 這裏是你的代碼,以熨平了錯誤:請注意BUFSIZEMAXNUM使用指定大小的只是讓你不必改變它在多個地方,如果你改變主意......

#include <stdio.h> 
#define BUFSIZE 20 
#define MAXNUM 10 
#define EXIT_FAILURE 0 

int main(int argc, const char* argv[]){ 
    int i, numIntegers; 
    char buffer[BUFSIZE]; 
    int intArray[MAXNUM]; 
    //if no argument is passed in, terminate 
    if (argc == 1){ 
      printf("no argument given, terminating..\n"); 
      return EXIT_FAILURE; 
    } 
    else{ 
      numIntegers = atoi(argv[1]); 
      //we only want numbers greater than 0 
      if (numIntegers <= 0 || numIntegers > MAXNUM){ 
        printf("# must be greater than 0 and less than %d!\n", MAXNUM); 
        return EXIT_FAILURE; 
      } 
      else{ 
        printf("Enter %d integer values to place in array: \n", numIntegers); 
        for (i = 0; i < numIntegers; i++){ 
          fgets(buffer, BUFSIZE, stdin); 
          intArray[i] = atoi(buffer); 
          printf("Index is = %d \n", i); 
        } 
      } 
    } 
} 

最後 - 你可能想知道爲什麼你的整數計數器似乎「復位」?那麼你的intArray是一個由10個整數組成的塊;並且當你聲明循環變量i時,它佔用內存中的下一個位置(因爲int intArray[10];是在到達for循環之前聲明變量的最後一次) - 當您「索引」到intArray[10]時碰巧遇到的情況(您不允許訪問的內存位置,但無論如何你都可以)。你碰巧輸入值2 - 因此,i重置爲2 ...

如果你在程序開始宣佈i(像我一樣,因爲我的編譯器不通過「做」 C99默認 - 我是那麼老!),問題會以不同的方式出現 - 或根本不存在。