1) В первой части вашей программы вы неправильно подсчитываете количество строк в файле.Фактическое количество строк в файле - 11, но ваша программа получает 10. Вам нужно начать считать с 1, так как в файле всегда будет хотя бы одна строка.Поэтому измените
int numLines = 0;
на
int numLines = 1;
2) Во второй части программы вы неправильно подсчитываете количество символов в каждой строке.Вы должны сохранить ваши инициализации счетчика одинаковыми.В начале сегмента вы инициализируете numChars равным 1. В этом случае вам необходимо сбрасывать счетчик на 1 после каждой итерации, поэтому измените:
numChars = 0;
на
numChars = 1;
Thisдолжен обеспечить достаточно места для всех непробельных символов и для конечного терминатора NULL.Помните, что в Си char * строки всегда заканчиваются NULL.
3) Ваша программа также не учитывает различий в завершении строки, но в моей тестовой среде это не проблема - fgetc возвращает только однусимвол для конца строки, даже если файл сохраняется с разделителями \ r \ n.
4) Во второй части вашей программы вы также не выделяете память для самой последней строки.Это приводит к вашей ошибке в третьей части вашей программы, когда вы пытаетесь получить доступ к нераспределенному пространству.
Обратите внимание, что ваш код сохраняет строки только в том случае, если они заканчиваются на \ r или \ n.Угадайте, что, EOF, который технически является окончанием строки для последней строки, не подходит.Поэтому ваш второй цикл не сохраняет последнюю строку в массиве.
Чтобы исправить это, добавьте это после второй части: textInFile [line] = (char *) malloc (sizeof (char) * numChars);
4) В выходных данных вашей программы вы видите эти странные восклицательные знаки, потому что вы не NULL завершаете свои строки.Поэтому вам нужно добавить строку, помеченную как NULL-завершение ниже:
if(charRead == '\n' || charRead == '\r')
{
textInFile[line][charNumber] = 0; // NULL termination
line++;
charNumber = 0;
}
5) Поскольку вы проверяете EOF, у вас возникает та же проблема в третьем цикле, поэтому вы должны добавить это до возврата
textInFile[line][charNumber] = 0; // NULL termination
6) У меня также возникают головные боли из-за всей структуры программы.Вы читаете один и тот же файл символ за символом 3 раза!Это очень медленно и неэффективно.
Фиксированный код следует ниже:
char** getLinesInFile(char *filepath)
{
FILE *file;
const char mode = 'r';
file = fopen(filepath, &mode);
char **textInFile;
/* Reads the number of lines in the file. */
int numLines = 1;
char charRead = fgetc(file);
while (charRead != EOF)
{
if(charRead == '\n' || charRead == '\r')
{
numLines++;
}
charRead = fgetc(file);
}
fseek(file, 0L, SEEK_SET);
textInFile = (char**) malloc(sizeof(char*) * numLines);
/* Sizes the array of text lines. */
int line = 0;
int numChars = 1;
charRead = fgetc(file);
while (charRead != EOF)
{
if(charRead == '\n' || charRead == '\r')
{
textInFile[line] = (char*) malloc(sizeof(char) * numChars);
line++;
numChars = 1;
}
else if(charRead != ' ')
{
numChars++;
}
charRead = fgetc(file);
}
textInFile[line] = (char*) malloc(sizeof(char) * numChars);
/* Fill the array with the characters */
fseek(file, 0L, SEEK_SET);
charRead = fgetc(file);
line = 0;
int charNumber = 0;
while (charRead != EOF)
{
if(charRead == '\n' || charRead == '\r')
{
textInFile[line][charNumber] = 0; // NULL termination
line++;
charNumber = 0;
}
else if(charRead != ' ')
{
textInFile[line][charNumber] = charRead;
charNumber++;
}
charRead = fgetc(file);
}
textInFile[line][charNumber] = 0; // NULL termination
return textInFile;
}