2013-10-08 2 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]); 
    //} 
} 

Вот результат, линия без другого текста, кроме целого, вводимый пользователем. Обратите внимание, как значение 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... 
} 

На самом деле - вот ваш код с ошибками сглажены: обратите внимание на использование определенных размеров для BUFSIZE и MAXNUM просто так вам не придется менять его в несколько мест, если вы передумали ...

#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 по default - я такой старый!), проблема возникла бы иначе - или совсем нет.

Смежные вопросы