2016-12-26 9 views
3

В следующем коде У меня есть uint8_t вектор заполняется из некоторых двоичного файла, который содержит информацию в some_size количества байт -новообращенного вектора uint8_t к BITSET

std::ifstream db(path.c_str(), std::ios::binary); 
std::vector <uint8_t> buffer(some_size, 0); 
db.read(reinterpret_cast<char *>(&buffer.front()), some_size); 
db.close(); 

Теперь я знаю, из какого-то индекса говорит 20, там существует 37 байт 1 или 0, которые необходимо заполнить в bitset. Битовый набор выглядит как std::bitset<37> booleans; и инициализируется для всех 0 s изначально. Теперь, если начальный индекс равен 20, поэтому мне нужно заполнить booleans 37 булевыми значениями, которые присутствуют в байтах, которые будут находиться в диапазоне от buffer[20] до buffer[56].

Помимо перекоса над вектором и вручную установки 1 или 0 на каждом бите в битрейте, есть ли другой способ преобразования этих байтов в этот битрейт?

+2

Я не вижу, как вы собираетесь конвертировать 'uint8_t' в тип' bitset', используя без написания цикла или с помощью функции, которая внутренне выполняет цикл для вас. В любом случае, цикл выполняется. – PaulMcKenzie

+0

@PaulMcKenzie of the course требуется цикл. Но ручная петля против использования чего-то типа 'std :: copy' или' std :: copy_n' - вот что я прошу здесь. –

+0

Проблема заключается в том, что у 'битета' нет итераторов, поэтому функции алгоритма, такие как' copy' или 'copy_n', будут с трудом делать то, что вы хотите. Вероятно, 'for_each' - лучшее, что вы можете сделать, [что-то вроде этого] (http://ideone.com/KyPbvU). – PaulMcKenzie

ответ

3

Поскольку вы не хотите, чтобы написать вручную кодированные петлю, вы можете использовать std::for_each:

#include <bitset> 
#include <cstdint> 
#include <vector> 
#include <algorithm> 

int main() 
{ 
    std::vector <uint8_t> buffer(100, 0); 
    std::bitset<37> b; 
    std::size_t i = 0; 
    std::for_each(buffer.begin() + 20, buffer.begin() + 57, [&](uint8_t val) 
    { b[i] = val; ++i; }); 
} 

Основной проблемой является то, что std::bitset не имеет итераторов, поэтому знакомые алгоритмы STL, такие как std::copy, std::copy_n, std::transform и т. д., для которых требуются итераторы, сложно, если не невозможно, использовать, если std::bitset является источником (или мишенью) функции алгоритма. Таким образом, кажется, что std::for_each с лямбдой, которая увеличивает индекс, будет работать.

+0

Отредактировано. Также [этот сайт] (http://en.cppreference.com/w/cpp/utility/bitset) - лучший сайт документации на C++. – PaulMcKenzie

+0

вы можете поместить 'i' в список захвата и сделать lambda mutable вместо того, чтобы объявлять его вне своей области, например:' [&, i = std :: size_t {0}] (uint8_t val) mutable .. .'. Это немного более многословно, но цель становится яснее. –

1

Вы можете сделать что-то вроде этого:

std::vector<uint8_t> sourceVec{1,0,1,1,0}; 
std::stringstream strStream; 
std::copy(sourceVec.begin(), sourceVec.end(), std::ostream_iterator<int>(strStream)); 
std::bitset<5> bitsetVar(strStream.str()); 
+0

Только пример. –