IMHO.WS

IMHO.WS (https://www.imho.ws/index.php)
-   Программирование (https://www.imho.ws/forumdisplay.php?f=40)
-   -   как записать bitset в бинарной форме? (https://www.imho.ws/showthread.php?t=129805)

crawler 21.02.2008 18:38

как записать bitset в бинарной форме?
 
чего-то туплю.
Код:


#include <bitset>
using namespace std;
.....
  bitset<8000> bs;
  ofstream myfile;
  myfile.open ("c:\\example.bin", ios_base::binary);
  myfile << bs;
  myfile.close();
  return 0;

в результате получаю текстовый файл размером 8К. А хотел бинарный размером 1к. с++, мс вижуал студио 2005.

А, самый цимес. В связи с большим размером сета, .to_ulong() кидает throw.

Hubbitus 21.02.2008 20:39

Полагаю Вам нужно перегрузить
std::ostream& operator<<(std::ostream& s, bitset<8000>& b)

Ну как-то так:
Код:

#include <fstream>
#include <iostream>
#include <bitset>

using namespace std;

typedef std::bitset<8000> myBitset;

std::ostream&
operator<<(std::ostream& s, myBitset& b){
std::string tmpStr(b.to_string());
        for (size_t i = 0; i<tmpStr.length(); i+=8*sizeof(char)){
        std::bitset<8*sizeof(char)> tb(tmpStr, i, 8*sizeof(char));
        s << (char)tb.to_ulong();
        }
return s;
};

int main(){

myBitset bs(65);
ofstream myfile;
myfile.open ("example.bin");
myfile << bs;
myfile.close();

return 0;
}

GCC 4.2.1, Linux


Цитата:

Сообщение от crawler (Сообщение 1524786)
А, самый цимес. В связи с большим размером сета, .to_ulong() кидает throw.

Самый что?? А что исключение - так резонно вполне, переполнение на таком размере очень даже вероятно.

crawler 22.02.2008 14:31

цимес - это национальное еврейское блюдо, из вареной моркови и изюма, сладенькое такое. по каким-то непонятным причинам считается деликатесом.

исключение - из-за того что размер битсета превышает "unsigned long". Так что действительно резонно. Я сначала хотел добавить преобразование в vector<unsigned long> и писть его, но так тоже неплохо. Правильность проверю в послезавтра на работе, но за наводку - большой спасиб.

Hubbitus 22.02.2008 23:56

За экскурс спасибо, что-такое цимес не знал :) Расширяю кругозор так сказать.

Цитата:

Сообщение от crawler (Сообщение 1525133)
Я сначала хотел добавить преобразование в vector<unsigned long> и писть его, но так тоже неплохо.

Ну тогда уж в vector<char>, или сразу в нужном виде формировать стандартную string нужного формата, также приблизительно как у меня в выводе перегруженном или подобным образом, рассматривая по 8 бит на символ (можно и в C-строку char * при большом желании) - иначе какой смысл делать лишние преобразования? Впрочем если оставаться все же в рамках C++ и STL и учитывая что задача стоит преобразовывать в такую бинарную форму только для вывода - думаю лучше именно перегрузить как в примере выше оператор вывода, или же перегрузить bitset::to_string() на собственную форму, чтобы она уже возвращала нужный вариант строки. Последний вариант будет сложнее для реализации и это придется наследовать bitset, поэтому имя у класса уже будет другое.
Да, ну и вообще я конечно проверял приведенный пример, в принципе он конечно же работает, хотя конечно может чего-то и не учел до конца - утверждать не буду, набросан на скорую руку.

crawler 23.02.2008 09:54

Смысл был в том, что внутреннее представление у битсета идет именно в "unsigned long", и именно чтобы не делать лишних преобразований. Со всем остальным полностью согласен.

Цитата:

Да, ну и вообще я конечно проверял приведенный пример, в принципе он конечно же работает
я не сомневаюсь в том, что код работал, но мой личный подход - тестировать все что можно, тем более чужой код. Даже если бы это был коммерческий код, я бы его тестил. Так что - без обид :beer:

Hubbitus 24.02.2008 00:52

Цитата:

Сообщение от crawler (Сообщение 1525377)
Смысл был в том, что внутреннее представление у битсета идет именно в "unsigned long"

И да и нет. Честно говоря не смотрел его реализацию, но могу утверждать что это заявление как минимум не верно для Вашего случая. В unsigned long уж точно никак не запихаешь 8000 бит :ржать:
Думаю в этом случае просто используется нечто вроде vector<bool> или подобные конструкции.

Но подозвеваю что для количества бит помещающегося в длинное целое для оптимизации наиболее вероятно какраз представлена подобная специализация данного шаблона в STL (не утверждаю правда что это именно так).


Никаких обид - конечно надо тестировать! Мало ли чего на форуме понапишут ;)

crawler 24.02.2008 11:26

Цитата:

В unsigned long уж точно никак не запихаешь 8000 бит
я имел в виду массив из "unsigned long" .
это вырезка из кода:
Код:

// TEMPLATE CLASS bitset
template<size_t _Bits>
        class bitset
        {        // store fixed-length sequence of Boolean elements
        typedef unsigned long _Ty;        // base type for a storage word
        enum {digits = _Bits};        // extension: compile-time size()

...............
private:
        enum
                {        // parameters for packing bits into words
                _Bitsperword = CHAR_BIT * sizeof (_Ty),        // bits in each word
                _Words = _Bits == 0
                        ? 0 : (_Bits - 1) / _Bitsperword};        // NB: number of words - 1

        _Ty _Array[_Words + 1];        // the set of bits
        };

НО! в связи с приватностью декларации, нефиг заморачиваться и действительно лучше перегрузить оператор << .

П.С. Можно на "ты" ?
П.П.С. а код таки рабочий :claps:


Часовой пояс GMT +4, время: 09:58.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.