Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
mishkazzz
0 / 0 / 0
Регистрация: 05.11.2013
Сообщений: 34
#1

Упаковка std :: vector <bool> в байты - C++

21.05.2014, 01:55. Просмотров 788. Ответов 14
Метки нет (Все метки)

Добрый Вечер!

возникла проблема:
нужно элементы
C++
1
std::vector<bool>
упаковать в байты для последующей записи в файл

собственно, вопроса два:
1. как это сделать?
2. как потом нужно поступить с файлом (какие функции использовать и открывать ли файл в бинарном режиме для этого?)

ps по форуму порылся, нашел обширные ответы только для bitset, а, насколько я понимаю, у vector немного другие возможности

заранее спасибо за помощь!
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.05.2014, 01:55
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Упаковка std :: vector <bool> в байты (C++):

Примерная реализация std vector bool - C++
добрый вечер, не могу найти в сети реализацию st::vector&lt;bool&gt; - есть у кого под рукой?) Почитать)

На основе исходного std::vector<std::string> содержащего числа, создать std::vector<int> с этими же числами - C++
подскажите есть вот такая задача. Есть список . Создать второй список, в котором будут все эти же числа, но не в виде строк, а в виде...

Как передать целочисленную матрицу типа std::vector<std::vector<int> > в функцию? - C++
Здравствуйте. Почитал на форуме, но так и не понял что я делаю не так. Имеется двумерный вектор. Размера .. Нужно его передать в...

Как изменять размер std::vector<std::vector>? - C++
Здравствуйте, как нужно изменять размер std::vector&lt;std::vector&gt; например: std::vector&lt;std::vector&lt;float&gt;&gt; data; ...

Вывести значения std::vector<std::vector<int*> > - C++
Подскажите, как вывести значения? const size_t row = 3; const size_t col = 3; std::vector&lt;std::vector&lt;int*&gt; &gt; imatrix; //...

Упаковка в байты - C++
Можно ли упаковать массив bitset допустим из 100 тысяч битов в байты, чтобы записать это дело в файл или можно записывать сразу в файл(но...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
outoftime
║XLR8║
510 / 432 / 33
Регистрация: 25.07.2009
Сообщений: 2,295
21.05.2014, 02:41 #2
mishkazzz, создаешь std::vecot<std::bitset<32>> и скидываешь туда все флаги.

http://en.cppreference.com/w/cpp/utility/bitset в качестве доки

Добавлено через 1 минуту
Для записи удобно конвертировать в uint_t и его записывать в бинарный файл.
1
mishkazzz
0 / 0 / 0
Регистрация: 05.11.2013
Сообщений: 34
21.05.2014, 02:47  [ТС] #3
outoftime,

хм,
vecot - это vector или что-то иное

и если vector, то
а "скинуть флаги" можно просто функцией swap или как?
и почему размер bitset'а 32?

спасибо за ответ!
0
nmcf
5319 / 4639 / 1551
Регистрация: 14.04.2014
Сообщений: 18,452
21.05.2014, 09:39 #4
Много в vector<bool> элементов? Выводи их просто последовательно в файл. Так же считывай.
0
mishkazzz
0 / 0 / 0
Регистрация: 05.11.2013
Сообщений: 34
21.05.2014, 11:29  [ТС] #5
nmcf, ну заранее неизвестно, сколько там элементов

мне необходимо именно упаковать в байты, а потом вывести в бинарный файл, дабы сжать объем
а вот если выводить в файл, мне кажется под них выделится опять бОльший объем
и я так думаю, что std::vector<std::bitset<32>> тоже потеряет свойство сжимать объем

можно ли каким-нибудь способом просто собрать байт из битов, именно взять и проставить в нем нужные биты внутри?

спасибо!
0
outoftime
║XLR8║
510 / 432 / 33
Регистрация: 25.07.2009
Сообщений: 2,295
21.05.2014, 11:30 #6
Цитата Сообщение от mishkazzz Посмотреть сообщение
и почему размер bitset'а 32?
Кол тебе за невнимательность.

Conversions

to_string

returns a string representation of the data
(public member function)

to_ulong


returns an unsigned long integer representation of the data
(public member function)

to_ullong

returns an unsigned long long integer representation of the data
(public member function)
to_ulong это к 32 битному число, т.е. можно делать битсет который записывается в файл минимум 32 битами.

В твоем случае, лучше использовать http://www.boost.org/doc/libs/1_55_0...ic_bitset.html

Вывод: есть 3 способа:
- использовать std::bitset
- boost::dinamic_bitset
- использовать char для представления каждого бита, т.к. байт - минимальная единица которую можно записать в файл, сокет и т.д., на плюсах.
1
newbie666
Заблокирован
21.05.2014, 11:48 #7
а размер чего ты хочешь уменьшить? размер файла? Что на каждый байт было по 8 значений bool - а ?
1
mishkazzz
0 / 0 / 0
Регистрация: 05.11.2013
Сообщений: 34
21.05.2014, 11:52  [ТС] #8
outoftime, да, про 32 понял, сейчас прочитаю то, что вы кинули
newbie666, мне нужно закодировать последовательность 0 и 1 5-битными кодами

и вот нужно реализовать именно то, что вы написали - чтобы 1 байт содержал в себе 8 значений bool по сути
0
newbie666
Заблокирован
21.05.2014, 11:56 #9
Цитата Сообщение от mishkazzz Посмотреть сообщение
5-битными кодами
а почему 5-и битными а не 1- битными? Ведь для BOOL Достаточно одного бита - то есть значение 0 или 1 ...
1
nmcf
5319 / 4639 / 1551
Регистрация: 14.04.2014
Сообщений: 18,452
21.05.2014, 12:00 #10
Ну упаковывай тогда по 8 элементов из vector в байт сдвигом и "или", потом записывай в файл.
1
newbie666
Заблокирован
21.05.2014, 12:13 #11
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
держи! Но тут как бы кол-во булов в векторе должно быть кратно степени двойки... Чтоб было не кратно - надо доработать обработку не полного байта последнего и писать в начало файла общее кол-во булов для последующего чтения...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <tchar.h>
#include <fstream>
#include <vector>
#include <bitset>
 
int _tmain(int argc, _TCHAR* argv[])
{
    const int dataSize = 65536;
    std::vector<bool> data;
    data.reserve(dataSize);
    for(int i = 0; i < dataSize; i++)
        data.push_back(rand()%2-1);
 
    std::fstream fs(L"bool.pak", std::ios::out | std::ios::binary);
    if(fs.is_open())
    {
        for(int i = 0; i < data.size(); i += 8)
        {
            std::bitset<8> bitByte;         
            for(int j = 0; j < 8; j++)
                bitByte[j] = data[i+ j];
            char oneByte = bitByte.to_ulong();
            fs.write(&oneByte, 1);          
        }
        fs.close();
    }
    
    return 0;
}
1
mishkazzz
0 / 0 / 0
Регистрация: 05.11.2013
Сообщений: 34
21.05.2014, 12:23  [ТС] #12
newbie666, ого! Спасибо вам огромное
Вот только вопрос, У меня в проге размер vector кратен 8, подойдет ведь?
0
newbie666
Заблокирован
21.05.2014, 12:30 #13
Цитата Сообщение от mishkazzz Посмотреть сообщение
У меня в проге размер vector кратен 8, подойдет ведь?
подойдёт, только в рамках моего кода постом выше размер вектора не должен быть меньше 8-и, а так - если он кратен 8-и и больше 8-и - то всё будет работать. Ну сам посмотри, я там просто кол-во итераций циклов захардкодил... Конечно можно сделать на любой размер вектора - но это надо будет ещё погемороиться ...

Добавлено через 3 минуты
да и ещё, если вектор огромный, то писать в файл по одному байту, собственно как и читать из файла по одному байте - крайне не эффективно, следует собрать всё в байтовый массив и одной операцией записи захреначить в файл (так же и читать)
0
outoftime
║XLR8║
510 / 432 / 33
Регистрация: 25.07.2009
Сообщений: 2,295
21.05.2014, 13:16 #14
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
newbie666, mishkazzz, не спешите господа.

Если нужно только 8 бит использовать, но можно либо создать свой тип либо класс для этого. Доступ к битам осуществляется как и у вектора, так что логику не поломает.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <bitset>
 
typedef std::bitset<8> byte1;
 
class byte2 : public std::bitset<8> {
public:
    uint8_t getByte() const {
        return static_cast<uint8_t>(this->to_ulong());
    }
};
 
int main () {
    byte1 b1;
    byte2 b2;
    b1[7] = true;
    b2[7] = true;
    std::cout << static_cast<uint8_t>(b1.to_ulong()) << ' ' << b2.getByte() << '\n';
}
Только с классом можно сразу определить методы ввода\вывода в файл или поток.
1
mishkazzz
0 / 0 / 0
Регистрация: 05.11.2013
Сообщений: 34
21.05.2014, 19:45  [ТС] #15
Спасибо всем огромное за помощь!

программу написал
то, что требует задача, она выполняет

однако работает ооочень долго, но это не беда
удачи!
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.05.2014, 19:45
Привет! Вот еще темы с ответами:

Std::vector<std::pair<std::vector<int>::iterator, std::vector<int>::iterator> - C++
Вопрос по вектору. Допустим есть вектор, std::vector&lt;int&gt; vec; на каком - то этапе заполнения я ставлю закладку итератора, ...

Std::vector/QVector в классе или std::vector/QVector классов? - C++
Доброе время суток! Собственно вопрос в самой теме, есть некий класс class WorkJornal { private: string manager; ...

Реализация класса MyString. Стандартная библиотека, std::string, std::vector - C++
как добавить реализацию конкатенации строк через перегрузку оператора &quot;+=&quot; в классе MyString и почему ошибка выдается???#include...

Передача функции указатель на элемент std::vector<std::string> - C++
Доброй ночи тем, кому не спится (или живет в другом часовом поясе:p)! Есть функция, требующая в качестве параметра указатель на...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
21.05.2014, 19:45
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru