Сначала вы открываете файл в режиме text :
fp = fopen(WORDS_FILENAME, "r");
В соответствии со C стандартом 7.21.9.4 Функция ftell , абзац 2 :
Функция ftell получает текущее значение индикатора положения файла для потока, на который указывает поток. Для двоичного потока значением является количество символов в начале файла. Для текстового потока его указатель положения файла содержит неопределенную информацию, используемую функцией fseek для возврата указателя положения файла для потока в его положение во время вызова ftell; разница между двумя такими возвращаемыми значениями не обязательно является значимым показателем количества написанных или прочитанных символов.
Вы не можете использовать ftell()
в текстовом потоке, чтобы сказать, сколько байты могут быть прочитаны.
Таким образом, вам придется открыть файл в режиме двоичный , чтобы использовать ftell()
(но см. примечание ниже):
fp = fopen(WORDS_FILENAME, "rb");
Теперь у вас есть размер файла:
fseek(fp, 0L, SEEK_END);
fsize = ftell(fp);
fseek(fp, 0L, SEEK_SET);
fcontent = (char*)calloc(fsize, sizeof(char));
Но , который не оставляет места для любого '\0'
терминатора, так что должно быть
// no need to cast a void * in C, and sizeof(char)
// is **always** one by definition
fcontent = calloc(fsize + 1 , 1);
Теперь вы будет иметь завершенную строку для содержимого файла.
Примечание о fseek()
в двоичном потоке
Использование fseek()
для достижения конца двоичного потока буквально неопределенное поведение в соответствии со стандартом C.
За 7.21.9.2 Функция fseek , пункт 3 :
Для двоичный поток, новая позиция, измеренная в символах от начала файла, получается путем добавления смещения к позиции, указанной в се. Указанная позиция является началом файла, если значение откуда SEEK_SET, текущим значением индикатора позиции файла, если SEEK_CUR, или концом файла, если SEEK_END. Бинарный поток не обязательно должен поддерживать вызовы fseek со значением откуда SEEK_END.
Сноска 268 четные состояния:
Установка индикатора положения файла в конец файла, как с fseek (file, 0, SEEK_END ), имеет неопределенное поведение для двоичного потока (из-за возможных завершающих нулевых символов) или для любого потока с кодированием, зависящим от состояния, которое не обязательно заканчивается в начальном состоянии сдвига.
Единственная причина, по которой вы можете использовать fseek(fp, 0L, SEEK_END);
, заключается в том, что большинство операционных систем расширяют язык C и фактически определяют его для работы.