все элементы массива являются одинаковыми fgets в C?

#c #arrays #file

#c #массивы #файл

Вопрос:

Итак, в настоящее время моя программа использует жестко запрограммированный массив, подобный этому:

 char *array[] = {"array","ofran","domle","tters", "squar"}
  

В основном n строк n длины «в n * n сетке. Затем я обрабатываю значения как 2D-массив. Итак, я получу доступ к array [y] [x] и выполню операции сравнения и вычисления, используя соответствующий ASCII.

Я хотел разрешить реализацию текстовых файлов различного размера (n * n) (до 32) в моей программе вместо жесткого кодирования. Но у меня возникают проблемы с использованием fgets.

Моя текущая функция для получения и хранения информации о файле выглядит следующим образом:

 char *array[32];
char buffer[32];
FILE *fp = fopen("textfile.txt","r");

int n = 0;
while(fgets(buffer, 32, fp)){
    array[i] = buffer;
    n  ;
}
fclose(fp);
  

но все значения «array» одинаковы (они являются последней строкой). То же самое с приведенными выше примерами значений. Если я напечатаю array [0] в array [4], я получу

значения из моего кода

 squar
squar
squar
squar
squar
  

ожидаемые значения:

 array
ofran
domle
tters
squar
  

Комментарии:

1. array[i] = buffer; просто присваивает один и тот же указатель всем элементам array . Здесь вам нужно динамическое выделение памяти или, возможно, 2d-массив char .

2. используйте strcpy вместо assign string .

3. @aragon использует strcpy вместо присваивания string No. Не делайте этого. Указатели в array относятся к постоянным строковым литералам фиксированной длины, возможно, доступным только для чтения.

Ответ №1:

array[i] = buffer просто присваивает один и тот же указатель всем элементам array . Здесь вам нужно динамическое выделение памяти:

 char *array[32];
char buffer[32];
FILE *fp = fopen("textfile.txt","r");

int n = 0;
while(fgets(buffer, 32, fp)){
    array[i] = strdup(buffer);  // allocate memory for a new string
                                // containing a copy of the string in buffer
    n  ;
}
fclose(fp);
  

Для краткости здесь проверка ошибок не выполняется. Также, если входной файл содержит более 32 строк, вы столкнетесь с проблемами.

если strdup не существует на вашей платформе:

 char *strdup(const char *str)
{
  char *newstring = malloc(strlen(str)   1);  //   1 for the NUL terminator
  if ( newstring )
    strcpy(newstring, str);
  return(newstring);
}
  

Опять же, проверка ошибок здесь не выполняется для краткости.

Комментарии:

1. Теперь вы пропустили return инструкцию. В один из таких дней? 🙂

Ответ №2:

Учитывая этот код:

 char buffer[32];
  

Сколько в нем buffer переменных?

Один.

Итак, этот код

 array[i] = buffer;
  

указывает каждый char * элемент array на ЕДИНИЦУ buffer .

(Одно из исправлений заключается в том, что @Jabberwocky опубликовал в своем ответе — use strdup() )

Ответ №3:

 char *array[32];
char buffer[32];
....    
while(fgets(buffer, 32, fp)){
    array[i] = buffer;
....
  

Посмотрите на свои переменные: первая — это массив из 32 указателей char *, вторая — массив из 32 символов.
В цикле while вы также просто присваиваете каждый элемент массива одному и тому же буферу. Вы видите? В то время как fgets просто продолжает обновлять этот буфер последними данными.