Чтение двоичного байта 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
.