По крайней мере, на первый взгляд кажется, что у этого есть пара проблем. Во-первых:
while ((line = strtok(buf, "\n\r"))) {
Чтобы использовать strtok
, вы обычно передаете буфер на first all, затем выполняете последующие вызовы, передавая "NULL" для первого параметра, пока strtok
не вернет NULL (указывая, что он достиг конца буфера). [Редактировать: после дальнейшего изучения становится очевидным, что это не является ошибкой - как указал @Casablanca, он устанавливает buf
в NULL в цикле, поэтому вторая и последующие итерации фактически делают pass NULL для первого параметра - поэтому текущий код немного сложен для понимания и (по крайней мере, возможно) несколько хрупок, но на самом деле не ошибается.]
Во-вторых, когда вы выделяете пространство, похоже, что вы не выделяете место для завершающего NUL:
res[i] = (char*)malloc(sizeof(char) * strlen(line));
По крайней мере, на первый взгляд, это выглядит так:
res[i] = malloc(strlen(line)+1);
[Кроме того, sizeof(char)==1
и приведение возврата от malloc
могут замаскировать ошибку при сбое на #include <stdlib.h>
для получения правильного прототипа в области видимости.]
Какой-то другой ваш код не совсем неправильный, но кажется мне менее читабельным, чем идеальный. Например:
j = 0;
while ((res[i][j] = tolower(line[j]))) {
j++;
}
Это довольно запутанный способ написания:
for (j=0; line[j] != '\0'; j++)
res[i][j] = tolower((unsigned char)line[j]);
Также обратите внимание, что когда вы вызываете tolower
, вам, как правило, нужно / вы хотите привести параметр к unsigned char
(передача отрицательного значения дает неопределенное поведение, и довольно много символов с ударениями, умляутами и т. Д. Обычно отображаются как отрицательные в типичном случае, когда char
подписано).
Кажется, у вас также есть утечка памяти - read_dict
вызывает readfile
, которая выделяет буфер (с calloc
- почему бы не malloc
?) И возвращает указатель на эту память в структуре. read_dict
получает структуру, но если я что-то пропустил, структура выходит из области видимости, и вы никогда не освобождаете память, на которую она указала.
Вместо того, чтобы пытаться найти и исправить проблему, которую вы видели, моя немедленная реакция - начать все сначала. Мне кажется, что вы сделали проблему значительно более сложной, чем она есть на самом деле. Если бы я делал это, я бы, вероятно, начал с функции для выделения пространства и чтения строки в пространство, что-то в следующем порядке:
// Warning: Untested code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *readline(FILE *file) {
char *buffer = NULL;
size_t current_size = 1;
char *temp;
const int block_size = 256;
do {
if (NULL == (temp = realloc(buffer, current_size+block_size)))
break;
buffer = temp;
buffer[current_size-1] = '\0';
if (fgets(buffer+current_size-1, block_size, file)==NULL)
return strlen(buffer) > 0 ? buffer : NULL;
current_size += block_size-1;
} while (strchr(buffer, '\n') == NULL);
strtok(buffer, "\n");
if (NULL != (temp = realloc(buffer, strlen(buffer)+1)))
buffer =temp;
return buffer;
}
Как только это сработает, чтение всех строк в файле и преобразование их в верхний регистр будет выглядеть примерно так:
// Warning: more untested code.
while (res[i] = readline(file)) {
size_t j;
for (j=0; res[i][j]; j++)
res[i][j] = toupper((unsigned char)res[i][j]);
++i;
}