Я начал возиться с функциями Fread/Fwrite в C. По сути, я работаю над программой, которая манипулирует данными в CSV-файле для моей задачи учета на конец месяца. Для моих файлов CSV функция fread()
работает (в целом) правильно. Я могу эффективно передавать CSV-файл на экран и т. д. Иногда я получаю ошибку чтения определенных байтов данных fread()!=подсчитанный/буферизованный элемент и выдает ошибку.
Из любопытства я запустил свою программу с файлами, отличными от CSV, а именно с файлом .png
. Похоже, что файл работает правильно в моей программе. Я могу сказать, что это так, поскольку моя программа работает так же, как и для файла CSV. Я настроил файл, чтобы он сообщал мне статистику (размер в символах) и т. д. в другой созданной мной функции. Я также установил программу, которая сообщает мне количество букв/символов в файле (от a до z). Когда я запускаю файл изображения, кажется, что программа обычно заполняет статические данные сверху; однако, когда я пытаюсь просмотреть поток, ничего не появляется, кроме PNG и вопросительного знака. Я ожидал, что появится как минимум тонна мусора, но ничего не получил. Почему поток ничего не показывает, несмотря на то, что приведенные выше статистические данные появляются? Мне интересно, связано ли это как-то с буфером или с какой-то внутренней проблемой операционной системы.
Проще говоря, fread()
наиболее подходит для двоичных данных. Файл CSV не является двоичными данными, поэтому fread()
обычно не подходит.
Это зависит от того, что вы собираетесь делать с данными, которые читаете. Если вы просто копируете его на стандартный вывод (терминал), все может быть в порядке.
Если вы получаете частичное чтение последнего блока файла, это не ошибка — это реальность, которая подскакивает и сообщает вам, что размер файла не кратен размеру блока, который вы используете для чтения данных. . Распечатайте прочитанные данные и, как правило, не пытайтесь прочитать больше. Вы можете подождать, пока не получите ноль от fread()
, прежде чем останавливаться (так что попробуйте еще раз). Это может быть уместно, если входные данные поступают, например, из канала.
Будьте осторожны с выбором механизма вывода. Если данные были прочитаны с помощью fread()
и вы не изменили их, возможно, уместно использовать fwrite()
. В противном случае следите за нулевыми байтами в данных, особенно если входные данные не являются текстовыми.
Спасибо за ваш ответ. Самое странное, что мой код работает относительно хорошо для файла CSV, но не для файла изображения. Я импортировал элементы fread() посимвольно (по одному символу за раз). В начале выполнения программы он предупреждает, что fread()!=count; однако поток, похоже, довольно близко соответствует файлу CSV. Однако когда я смотрю на файл изображения, поток вообще не отображается. Судя по вашим словам, я ожидал обратного.
Не видя вашего кода, трудно сказать, что происходит. У вас может быть функция void copy_file(FILE *ifp, FILE *ofp) { char buffer[1024]; size_t nbytes; while ((nbytes = fread(buffer, sizeof(char), sizeof(buffer), ifp)) != 0) { size_t obytes; if ((obytes = fwrite(buffer, sizeof(char), nbytes, ofp)) != nbytes) { fprintf(stderr, "%s(): short write (%zu bytes expected; %zu bytes written\n", __func__, nbytes, obytes); return; } } }
, которая будет точно, байт за байтом, копировать входной поток (ifp
) в выходной поток (ofp
). Вероятно, ваш код более сложен.
Поскольку в вопросе говорится только в общих чертах без указания кода, на него трудно ответить иначе, чем в общих чертах. Если код предназначен для манипулирования данными CSV, вероятно, использовать
fread()
нецелесообразно. Вероятно, вам следует предоставить что-то похожее на MCVE (Минимальный, полный, проверяемый пример — или MRE, или любое другое имя, которое сейчас использует SO) или SSCCE ( Короткий, автономный, правильный пример — та же идея, но в другом имя).