Чтение двоичного байта istream by byte

Я пытался прочитать байтовый байтовый файл байтом, используя ifstream. Я использовал методы istream, такие как get(), прежде чем читать целые куски двоичного файла сразу без проблем. Но моя текущая задача поддается байту за байтом и полагается на буферизацию в io-системе, чтобы сделать ее эффективной. Проблема в том, что я, казалось, доходил до конца файла несколько байт раньше, чем должен. Поэтому я написал следующую тестовую программу:

#include <iostream>
#include <fstream>

int main() {
    typedef unsigned char uint8;
    std::ifstream source("test.dat", std::ios_base::binary);
    while (source) {
        std::ios::pos_type before = source.tellg();
        uint8 x;
        source >> x;
        std::ios::pos_type after = source.tellg();
        std::cout << before << ' ' << static_cast<int>(x) << ' '
                  << after << std::endl;
    }
    return 0;
}

Отбрасывает содержимое test.dat, по одному байту в строке, показывая позицию файла до и после.

Конечно, если у моего файла есть двухбайтная последовательность 0x0D-0x0A (что соответствует возврату каретки и фиду линии), эти байты пропускаются.

  • Я открыл поток в двоичном режиме. Разве это не мешает интерпретации разделителей строк?
  • Операторы выделения всегда используют текстовый режим?
  • Каков правильный способ чтения байта байтом из двоичного istream?

MSVС++ 2008 в Windows.

Ответы

Ответ 1

Экстракторы → для форматированного ввода; они пропускают пробелы (по по умолчанию). Для неформатированного ввода с одним символом вы можете использовать istream::get() (возвращает int, либо EOF, если сбой чтения, либо значение в диапазоне [0, UCHAR_MAX]) или istream::get(char&) (помещает символ, прочитанный в аргументе, возвращает то, что преобразуется в bool, true, если чтение преуспевает, и false, если оно не работает.

Ответ 2

есть функция read(), в которой вы можете указать количество байтов.

Ответ 3

Почему вы используете форматированное извлечение, а не .read()?

Ответ 4

source.get()

предоставит вам один байт. Это неформатированная входная функция. operator → - это форматированная входная функция, которая может означать пропуски пробельных символов.

Ответ 5

Как уже упоминалось, вы должны использовать istream::read(). Но, если вы должны использовать форматированное извлечение, рассмотрите std::noskipws.