Кажется, вы полагаете, что все строки имеют одинаковую длину. Если это так, у вас все еще есть проблемы:
память для указателей строк выделена неправильно, она должна быть
char **genome = calloc(line_count, sizeof(char *));
или лучше и меньше подвержено ошибкам:
char **genome = calloc(line_count, sizeof(*genome));
память для каждой строки должна быть на один байт длиннее нулевого терминатора.
\n
- строка формата fscanf()
соответствует любой последовательности символов пробела. Это избыточно, поскольку %s
все равно пропускает их.
безопаснее подсчитывать элементы, разделенные пробелами, чтобы избежать неправильного подсчета элементов, если файл содержит какие-либо пустые символы.
вы не закрываете file
.
вы не возвращаете genome
в конце функции
вы не проверяете на наличие ошибок.
Вот модифицированная версия:
void **get_genome(const char *filename) {
FILE *file = fopen(filename, "r");
if (file == NULL)
return NULL;
int line_count = 1;
int item_count = 0;
int item_length = -1;
int length = 0;
int c;
while ((c = getc(file)) != EOF) {
if (isspace(c)) {
if (length == 0)
continue; // ignore subsequent whitespace
item_count++;
if (item_length < 0) {
item_length = length;
} else
if (item_length != length) {
printf("inconsistent item length on line %d\", line_count);
fclose(file);
return NULL;
}
length = 0;
} else {
length++;
}
}
if (length) {
printf("line %d truncated\n", line_count);
fclose(file);
return NULL;
}
rewind(file);
char **genome = calloc(item_count, sizeof(*genome));
if (genome == NULL) {
printf("out of memory\n");
fclose(file);
return NULL;
}
for (int i = 0; i < item_count; i++) {
genome[i] = calloc(item_length + 1, sizeof(*genome[i]));
if (genome[i] == NULL) {
while (i > 0) {
free(genome[i]);
}
free(genome);
printf("out of memory\n");
fclose(file);
return NULL;
}
fscanf(file, "%s", genome[i]);
}
fclose(file);
printf("%d items of %d length on %d lines\n",
item_count, item_length, line_count);
for (int i = 0; i < item_count; i++)
printf("%s\n", genome[i]);
return genome;
}