Ваша проблема в том, что вы повторно используете массив entry
.
Посмотрите, как для всех i
у нас есть fragments[i++] = entry;
. В конце каждый фрагмент будет указывать на одно и то же место и, следовательно, будет содержать одну и ту же строку (в этом случае это будет последняя прочитанная строка).
Кажется, что вы пытались обойти это, используя оба массива temp
и entry
, но в итоге вы могли бы точно также сделать запись fscanf
непосредственно в массив entry
.
Другая проблема, которую вы можете получить, - это если ваши указатели указывают на массив, который был автоматически размещен в стеке (т. Е .: массив, объявленный внутри функции). Эти места в памяти повторно используются вашей программой после возврата из вашей функции, ваши указатели могут начать указывать на недопустимые данные (и поскольку это C, использование этих поврежденных строк может привести к всевозможным сбоям и плохому поведению программы).
Ваша проблема в основном связана с распределением памяти, поэтому существует множество решений.
Сделать fragments
массивом символьных массивов (вместо только указателей). Таким образом, у вас есть отдельный кусок памяти для каждой строки.
char fragments[2000][20]; //can hold 2000 19-character strings
for(i=0; i<N; i++){
scanf("%d", fragments[i]);
}
Преимущество этого решения в том, что оно простое и вся память выделяется заранее.
Использовать динамическое выделение памяти с malloc
. Это позволяет вам выбирать различный размер массива для каждой строки, а также позволяет выбирать размер ваших массивов во время выполнения вместо времени компиляции.
char* fragments[2000];
char entry[MAX_FRAGMENT_LENGTH]; //temporary buffer for strings
for(i=0; i<N; i++){
scanf("%d", entry[i]);
//dynamically allocate an array, just big enough to fit our string in.
fragments[i] = malloc(sizeof(char) * (1 + strlen(entry));
strcpy(fragments[i], entry);
}
Основным преимуществом этого метода является то, что он очень гибкий, но при этом достаточно простой. Основным недостатком является то, что вам нужно будет free
все указатели, которые были malloc
-оданы после того, как вы их сделали (в противном случае вы можете получить утечку памяти).
Выполните «динамическое выделение» вручную, используя один большой буфер для хранения всех строк.
char buffer[2000*20];
char* fragments[2000];
char* next_empty_location = buffer;
for(i=0; i<N; i++){
scanf("%d", next_empty_location);
fragments[i] = next_empty_location;
next_empty_location += strlen(next_empty_location) + 1;
}
Если вы не можете / не хотите / не можете использовать решение malloc
, это то, что ближе всего. Это может быть труднее понять (в случае, если у вас возникли проблемы с C), но лучше всего оно подходит для смутного ограничения «каждый символ *, который содержит строку, будет точной длиной строки».