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

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

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

В основном n строк длины n "сетка n * n. Затем я обрабатываю значения как двумерный массив. Поэтому я буду обращаться к массиву [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);

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

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

squar
squar
squar
squar
squar

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

array
ofran
domle
tters
squar
array[i] = buffer; просто присваивает один и тот же указатель всем элементам array. Здесь вам нужно динамическое выделение памяти или, может быть, двумерный массив char.
Jabberwocky 15.03.2019 11:27

используйте strcpy вместо назначения строки.

aragon 15.03.2019 11:29

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

Andrew Henle 15.03.2019 11:32
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
207
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

char buffer[32];

Сколько buffer переменных существует?

Один.

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

array[i] = buffer;

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

(Одно из решений — сделать @Jabberwocky опубликованным в его ответе — используйте strdup())

Ответ принят как подходящий

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);
}

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

Теперь вы пропустили утверждение return. Один из тех дней? :-)

Andrew Henle 15.03.2019 13:11
char *array[32];
char buffer[32];
....    
while(fgets(buffer, 32, fp)){
    array[i] = buffer;
....

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

Другие вопросы по теме