C++ побайтовое считывание

275
03 июля 2022, 03:10

Я пытаюсь считать каждый байт из файла в буфер и вывести его:

FILE* f_stream = fopen("C:\\Users\\Neo\\source\\repos\\mt_2_lab_3\\Debug\\myfile.txt", "rb");
size_t bytes_read = 0;
char* buf[1];
if (f_stream == NULL)
    printf("\nFile stream open failed!\n");
else
{
    printf("\nFile stream successfully opened!\n");
    while ((bytes_read = fread(buf, 1, sizeof(buf), f_stream)) > 0)
    {
        cout << buf << endl;
    }
}

Файл myfile.txt содержит такой текст: abs

Вывод программы:

File stream successfully opened!
002AF5D8

Хотя я ожидал, что будет:

a
b
s

Если сделать так:

cout << (char)buf << endl;

То каждый раз выводит 1 рандомный символ

Если сделать так:

cout << buf[0] << endl;

То происходит ошибка "Вызвано исключение по адресу 0x1001FF5C (ucrtbased.dll) в mt_2_lab_3.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0xCC736261"

Что я делаю не так? В будущем хочу считывать не по 1 байту, а например по 256 и обрабатывать эти 256 байт.

Answer 1

Можно каждый байт читать таким способом:

#include <iostream>
#include <fstream>
int main() {
    std::ifstream file("myfile.txt");
    if (!file) return 1;
    char b;
    while (file.get(b)) {
        std::cout << b << std::endl;
    }
    file.close();
    return 0;
}
Answer 2

Декларация массива

char * buf [ 1 ] ;

хранит один указатель на букву, а вам нужен массив букв :

char  buf [ 256 ] ;

Печать буфера как вы хотели

cout << buf << endl;

приведёт к краху программы, так как поток std :: stream думает, что это указатель на строку а не на массив и ищет там байт конца строки.

Печать байтов как буквы плохая идея, так как в файлах существуют непечатные символы, это символы управления (цвет, обнуление экрана, перенос курсора и т.д.)

Только циклом с проверкой что символ печатный.

# include <ctype.h>
for(int i=0;i<256;++i) {
  cout << "код = " << ( unsigned int ) ( buf [ i ] ) << " " ;
  if ( isprint ( buf [ i ] ) )
    cout << "буква = '" << buf [ i ] << "' " << endl ; }
READ ALSO
Текстурные швы (искажения) при наложении на сферу OpenGL

Текстурные швы (искажения) при наложении на сферу OpenGL

При наложении текстуры на сферу получаю искажение на полюсах (рис1), швы вдоль сферы особо не видны, но если убрать GL_REPEAT в

239
Вывод списка процессов Windows 10 в компонент Qt

Вывод списка процессов Windows 10 в компонент Qt

При написании курсового проекта столкнулся с проблемой: при нажатии на компонент MenuBar у меня не происходит вывод значений на компонент TableWidget...

236
QListWidget проверка на выделение

QListWidget проверка на выделение

Как правильно организовать проверку на выделение какого-либо элемента QListWidgetВ пример прилагаю мой QListWidget с таймерами - элементами списка

407