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

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

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 байт.


Ответы (2 шт):

Автор решения: AlexGlebe

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

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 ; }
→ Ссылка
Автор решения: TigerTV.ru

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

#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;
}
→ Ссылка