2014-10-27 2 views
3

Я прочитал an answer here, показывающий, как читать весь поток в станд :: строку со следующим один (два) лайнера:Как читать весь поток в std :: vector?

std::istreambuf_iterator<char> eos;  
std::string s(std::istreambuf_iterator<char>(stream), eos); 

Для делать что-то подобное, чтобы прочитать двоичный поток в std::vector, то почему» t Я просто заменяю char на uint8_t и std::string с std::vector?

auto stream = std::ifstream(path, std::ios::in | std::ios::binary);  
auto eos = std::istreambuf_iterator<uint8_t>(); 
auto buffer = std::vector<uint8_t>(std::istreambuf_iterator<uint8_t>(stream), eos); 

выше выдает ошибку компиляции (VC2013):

1> d: \ не-Svn \ C++ \ библиотеки \ я \ файл \ filereader.cpp (62): Ошибка C2440: '': не удается преобразовать из 'станд :: basic_ifstream>' в 'станд :: istreambuf_iterator>' 1>
с 1> [1> _Elem = uint8_t 1>] 1>
нет конструктор не мог взять источник тип или перегрузка конструктора разрешение было неоднозначным

+0

Основываясь на сообщении об ошибке '' char' и uint8_t' не то же самое, на ваш компилятор. Вместо этого попробуйте использовать 'char'. – cdhowie

+0

@cdhowie 'uint8_t' is' unsigned char', так что да, не то же самое на любом компьютере;) Но да, это, вероятно, неоднозначный актерский состав, поскольку вывод для 'ifstream' -' 'char''. – aruisdante

+0

Да, он работает с символом char, но uint8_t является символом без знака. – Robinson

ответ

9

Существует только несоответствие типа. ifstream просто ЬурейеЕ:

typedef basic_ifstream<char> ifstream; 

Так что, если вы хотите использовать другой базовый тип, вы просто должны сказать ему:

std::basic_ifstream<uint8_t> stream(path, std::ios::in | std::ios::binary);  
auto eos = std::istreambuf_iterator<uint8_t>(); 
auto buffer = std::vector<uint8_t>(std::istreambuf_iterator<uint8_t>(stream), eos); 

Это работает для меня.

Или, так как Дитмар говорит, что это может быть немного схематичны, вы могли бы сделать что-то вроде:

auto stream = std::ifstream(...); 
std::vector<uint8_t> data; 

std::for_each(std::istreambuf_iterator<char>(stream), 
       std::istreambuf_iterator<char>(), 
       [&data](const char c){ 
        data.push_back(c); 
       }); 
+0

Ах. Конечно. Спасибо. – Robinson

+0

Это довольно удивительно, если это действительно работает!Это компиляция _may_, но я не могу представить, что это выполняется из коробки: создание потока для символьного типа, отличного от 'char' или' wchar_t', конечно, не обязательно будет работать сразу, как целое число необходимых фасеты не обязательно должны предоставляться. Для конкретной необходимости я ожидал бы, что по крайней мере 'std :: codecvt ' отсутствует (я не уверен, что какой-либо другой фасет действительно требуется). –

+0

Если это не должно работать из коробки, я полагаю, я не должен этого делать. Я хотел бы различать двоичный поток и двоичные данные и текстовый поток и текстовые данные. Поэтому я собирался использовать uint8_t для двоичных данных и символов для текста. Я полагаю, что идиоматично использовать char для всего ... – Robinson

5

ifstream - это поток char, а не uint8_t. Вам нужны либо basic_ifstream<uint8_t>, либо istreambuf_iterator<char> для соответствующих типов.

Первый не может работать без какой-либо работы, поскольку библиотека требуется только для поддержки потоков char и wchar_t; поэтому вы, вероятно, захотите istreambuf_iterator<char>.

+0

... и создание 'std :: basic_ifstream ' довольно нетривиально! –

+0

@ DietmarKühl: Хорошая точка. Обычно я избегаю мутной глубины библиотеки ввода-вывода, поэтому не могу точно помнить, что она поддерживает. –

Смежные вопросы