2015-12-15 7 views
-1

Учитывая файл, содержащий следующий шестнадцатеричный код: 0B 00 00 00 00 00 20 41istream_iterator перебирать байтов в бинарном файле

Я пытаюсь населён станд :: вектор < зЬй :: uint8_t >, а затем проверять каждый байт вручную.

Вот код, где я создаю свой вектор из двух StD :: istream_iterators с помощью итератора конструктор

using Bytes = std::vector<std::uint8_t>; 
using ByteItr = std::istream_iterator<std::uint8_t>; 

Bytes getBytes() 
{ 
    std::ifstream in; 
    in.open("filepath"); 
    in.seekg(0, std::ios::beg); 
    Bytes bytes; 
    ByteItr start(in); 
    ByteItr end; 
    return Bytes(start, end); 
} 

Вот тест блок я пытаюсь передать его через:

auto bytes = getBytes(); 

REQUIRE(bytes.size() == 8); 

CHECK(bytes[0] == 0x0B); 
CHECK(bytes[1] == 0x00); 
CHECK(bytes[2] == 0x00); 
CHECK(bytes[3] == 0x00); 
CHECK(bytes[4] == 0x00); 
CHECK(bytes[5] == 0x00); 
CHECK(bytes[6] == 0x20); 
CHECK(bytes[7] == 0x41); 

Почему заключается в том, что в этом контексте он пропускает два элемента и неявно преобразует мой вектор std :: uint8_t в unsigned chars?

+2

Не могли бы вы пояснить, что вы подразумеваете под словом «он пропускает два элемента и неявно преобразует мой вектор std :: uint8_t в неподписанные символы», пожалуйста? – RiaD

+1

Также, как только вы откроете свой файл, вы можете просто «вернуть {ByteItr {in}, ByteItr {}};', вам не нужно «искать» до начала ... – Barry

+0

@RiaD Я имею в виду, что он возвращает только 6 элементов, где ожидается 8. Мой список также преобразуется в ** std :: vector ** при вызове функции. – Burtonium

ответ

8

istream_iterator следует не используется для чтения двоичных файлов. Он использует operator>>, что также не подходит для чтения двоичных файлов (если только эти файлы не имеют особого формата, большинство из которых не имеют двоичных файлов поместиться). Вместо этого вы можете использовать istreambuf_iterator. Вы также хотите открыть файл в двоичном режиме.

in.open("filepath", std::ios::in | std::ios::binary); 
+0

Это сработало, спасибо. – Burtonium

4

Не использовать std::istream_iterator<T>: это предназначено для ввода текста в формате. Скорее всего, это будет пропускать пробелы, например, (вы можете отключить пропуск пространства с помощью std::noskipws, но это все же не так, что нужно сделать. Используйте std::istreambuf_iterator<char> вместо (тип char тип символа, если поток).

Кроме того, когда обрабатывая двоичные данные, убедитесь, что ваш поток открыт в двоичном режиме, чтобы избежать переходов на конец строки (в случае, если вы попробуете сделать это на платформе, делая конверсии конца строки). То есть вы должны std::ios_base::binary в открытый режим.