Объявление типа char *array[i][j]
с i==0
и j==0
зарезервирует массив размера 0, так что четная позиция array[0][0]
юридически недоступна (неопределенное поведение).Поэтому, когда вы пишете array[i][j] = malloc(lines * sizeof(char*))
, вы уже пишете array[0][0]
, что приводит к UB.
Обычно сообщество наказывает человека за то, что он предоставил решение кому-то, обращающемуся за помощью, и тем самым предоставил ему возможность самостоятельно получить опыт.Для вашего уровня зрелости, однако, мне кажется, что это тяжелое упражнение, и поэтому я предоставлю решение, следуя вашему подходу, и опишу то, что следует учитывать.
Надеюсь, это поможет.
При вашем подходе вам нужно ...
- считать слова
- выделять место для "слов * sizeof (char *)" + одно слово для хранения
NULL
- указатель в конце (иначе пользователи вашего результата не будут знать, где остановиться). - перематывать и читать каждое слово в цикле;
- в цикле, сделатьскопируйте содержимое временного слова и сохраните его в массиве
- после цикла, запишите окончательный NULL-указатель.
- верните массив (и сообщите пользователю, что ему придется освободить памятьпозже)
Вот код:
char** fill_word_array(char* filename){
int words = 0;
char str[100];
char **array;
FILE * fp = fopen("words.txt", "r");
if (fp == NULL)
{
printf("Cannot open file");
return 0;
}
while (fscanf(fp, "%s", str) != EOF)
{
words++;
}
printf("%d\n", words);
fseek(fp, 0, SEEK_SET);
array = malloc(sizeof(char*) * (words+1));
for(int i = 0; i < words && fscanf(fp, "%s", str) != EOF; i++)
{
array[i] = strdup(str);
}
array[words] = NULL;
return array;
}
int main() {
char **array = fill_word_array("someFile.txt");
for (int i=0; array[i] != NULL; i++) {
printf("%s\n", array[i]);
free(array[i]);
}
free(array);
}