Почему Fread работает только с определенными файлами?

Я начал возиться с функциями Fread/Fwrite в C. По сути, я работаю над программой, которая манипулирует данными в CSV-файле для моей задачи учета на конец месяца. Для моих файлов CSV функция fread() работает (в целом) правильно. Я могу эффективно передавать CSV-файл на экран и т. д. Иногда я получаю ошибку чтения определенных байтов данных fread()!=подсчитанный/буферизованный элемент и выдает ошибку.

Из любопытства я запустил свою программу с файлами, отличными от CSV, а именно с файлом .png. Похоже, что файл работает правильно в моей программе. Я могу сказать, что это так, поскольку моя программа работает так же, как и для файла CSV. Я настроил файл, чтобы он сообщал мне статистику (размер в символах) и т. д. в другой созданной мной функции. Я также установил программу, которая сообщает мне количество букв/символов в файле (от a до z). Когда я запускаю файл изображения, кажется, что программа обычно заполняет статические данные сверху; однако, когда я пытаюсь просмотреть поток, ничего не появляется, кроме PNG и вопросительного знака. Я ожидал, что появится как минимум тонна мусора, но ничего не получил. Почему поток ничего не показывает, несмотря на то, что приведенные выше статистические данные появляются? Мне интересно, связано ли это как-то с буфером или с какой-то внутренней проблемой операционной системы.

Поскольку в вопросе говорится только в общих чертах без указания кода, на него трудно ответить иначе, чем в общих чертах. Если код предназначен для манипулирования данными CSV, вероятно, использовать fread() нецелесообразно. Вероятно, вам следует предоставить что-то похожее на MCVE (Минимальный, полный, проверяемый пример — или MRE, или любое другое имя, которое сейчас использует SO) или SSCCE ( Короткий, автономный, правильный пример — та же идея, но в другом имя).

Jonathan Leffler 03.06.2024 06:39
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
61
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проще говоря, fread() наиболее подходит для двоичных данных. Файл CSV не является двоичными данными, поэтому fread() обычно не подходит.

Это зависит от того, что вы собираетесь делать с данными, которые читаете. Если вы просто копируете его на стандартный вывод (терминал), все может быть в порядке.

Если вы получаете частичное чтение последнего блока файла, это не ошибка — это реальность, которая подскакивает и сообщает вам, что размер файла не кратен размеру блока, который вы используете для чтения данных. . Распечатайте прочитанные данные и, как правило, не пытайтесь прочитать больше. Вы можете подождать, пока не получите ноль от fread(), прежде чем останавливаться (так что попробуйте еще раз). Это может быть уместно, если входные данные поступают, например, из канала.

Будьте осторожны с выбором механизма вывода. Если данные были прочитаны с помощью fread() и вы не изменили их, возможно, уместно использовать fwrite(). В противном случае следите за нулевыми байтами в данных, особенно если входные данные не являются текстовыми.

Спасибо за ваш ответ. Самое странное, что мой код работает относительно хорошо для файла CSV, но не для файла изображения. Я импортировал элементы fread() посимвольно (по одному символу за раз). В начале выполнения программы он предупреждает, что fread()!=count; однако поток, похоже, довольно близко соответствует файлу CSV. Однако когда я смотрю на файл изображения, поток вообще не отображается. Судя по вашим словам, я ожидал обратного.

Ratdude 03.06.2024 12:36

Не видя вашего кода, трудно сказать, что происходит. У вас может быть функция 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). Вероятно, ваш код более сложен.

Jonathan Leffler 03.06.2024 15:01

Другие вопросы по теме