» »

[C++] Zapis vector<BOOL> v binarno datoteko

[C++] Zapis vector<BOOL> v binarno datoteko

c0dehunter ::

Zdravo, iščem že nekaj časa pa ne najdem načina za pravilni izpis vector strukture v datoteko (le-ta je binarna).
Stvar je taka da imam v vectorju shranjene samo 0 in 1, zato uporabljam kar "vector < BOOL > izhod".

CStdioFile dat;
dat.Open("stisnjena_datoteka.bin", CFile::modeCreate | CFile::modeReadWrite | CFile::typeBinary);
dat.Write(&izhod[0],sizeof(BOOL)*izhod.size());
dat.Close();


Vendar izpis ni pravilen. Pomoč, plz! ;)

/*popravek:
če uporabim vector< char >, dobim v datoteki sicer pravi izpis, vendar je vsaka 1 oz. 0 velika en bajt namesto en bit..
I do not agree with what you have to say,
but I'll defend to the death your right to say it.

Vesoljc ::

kako pa izgleda zapis?
Abnormal behavior of abnormal brain makes me normal...

c0dehunter ::

Če uporabim vector< BOOL > dobim prazno datoteko.
I do not agree with what you have to say,
but I'll defend to the death your right to say it.

Vesoljc ::

prazno as in size == 0, al same nicle?

dvomim da bo to slo na tak nacin. bool je namrec velik 1 byte, tako kot char. ce nic drugega bi moral dobiti isti zapis kot s charom. za kaj takega rabis bitstream, oz. stl::bitset

http://www.cplusplus.com/reference/stl/...
Abnormal behavior of abnormal brain makes me normal...

Zgodovina sprememb…

  • spremenil: Vesoljc ()

c0dehunter ::

Ok, bom poskusil narediti tako: vsakič naredim bitset velikosti 8, vzamem 8 bool vrednosti iz mojega vector arraya,zapišem ta bitset v datoteko in ponavljam dokler ne pridem do konca vector arraya. Upam da bo šlo.
I do not agree with what you have to say,
but I'll defend to the death your right to say it.

Vesoljc ::

zakaj pa vector kar ne zamenjas z bitsetom pa je... sicer ga moras presizat ampak bo itaq majn prostora zasedu kot vector boolov...
Abnormal behavior of abnormal brain makes me normal...

xordie ::

Bool vector je izjema. Deluje ko bitset vendar je se vedno dinamicen kot navaden vector.
x

c0dehunter ::

Problem pri bitsetu, če bi ga uporabil namesto vector bool je, da ne vem niti približno njegove velikosti in ga ne morem inicializirat.

@xordie: to pomeni da je vsak bool znotraj vectorja potemtakem res samo en bit?

/*edit:
da si sam odgovorim na zgornje vprašanje - Ja (bit_vector) :)

Sedaj samo še pogruntam kako 8 bitov iz vectorja spravit v char in to zapisat.
I do not agree with what you have to say,
but I'll defend to the death your right to say it.

Zgodovina sprememb…

mn ::

@xordie: to pomeni da je vsak bool znotraj vectorja potemtakem res samo en bit?


To velja za std::vector<bool>, ne vem pa če velja za BOOL (verjetno ne)! Če pogledaš je BOOL zelo verjetno deklariran kot :
typedef int                 BOOL;

Kar pomeni da je sizeof(BOOL) 4 byte in posledično imaš v resnici vector<int>!
Na kratko to pomeni, da tale koda :
sizeof(BOOL)*izhod.size()
vrne 32 za 8 BOOLov in ne 1 kakor po moje ti pričakuješ.

Vendar nič od tega ne pojasni zakaj je tvoja datoteka prazna. Kakor sem videl v dokumentaciji naj bi CStdioFile vrnil exception če gre kaj narobe. Si prepričan da ne dobiš kakšnega exceptiona?
Poleg tega: zakaj delaš z MFCjem? Imaš kak dober razlog za to, da ne uporabiš standardnih C++ funkcij?

c0dehunter ::

mn, hvala za opozorilo, sam ne vem zakaj sem šel uporabljat BOOL namesto bool. Tudi to sem ugotovil ja, da je dejansko št. elementov kar izhod.size().

Če sedaj v datoteko pišem tako:
dat.Write(&izhod[0],izhod.size());

dobim datoteko velikosti 8 bytov (št. elementov v vectorju je bilo 8) in ni prazna (zgleda da sem včeraj še nekaj narobe delal). Verjetno pa bi mogla biti velika 1, največ 2 byta.

Tako da trenutno delam na metodi, ki sem jo opisal v enem izmed zgornjih postov (zapis s pomočjo bitsetov). Edina težava je primer, ko število elementov v vectorju ni deljivo z 8 -kaj zapisat v zadnji bitset?

V MFCju delam pa zato, ker tako zahtevajo "navodila" ;)
I do not agree with what you have to say,
but I'll defend to the death your right to say it.

Zgodovina sprememb…

mn ::

dobim datoteko velikosti 8 bytov (št. elementov v vectorju je bilo 8)

Si preveril kaj točno imaš v datoteki. Če je tvoja verzija vector>bool< res implementirana z bitsetom pol bi moral za 8 elementov zapisati 8 bitom == 1 bajt. Torej bi moralo biti nekaj takšnega:
dat.Write(&izhod[0],(izhod.size()+7)/8);

S +7 trikom zagotoviš, da zaokrožaš navzgor.

Glede drugega problema pa bi jaz v datoteko zapisal velikost polja na prvo mesto:
dat.Write(izhod.size(),sizeof(size_t));

Torej če imaš vector z elementi 11001011 pričakuješ v datoteki:
00 00 00 08 CD
Prvi štirje bajti so dolžina vectorja, zadnji bajt je pa bitset. Drugi primer je pa
Torej če imaš vector z elementi 110010111 pričakuješ v datoteki:
00 00 00 09 CD 80
S tem, da je zadnji bajt lahko kar koli. Vse kar veš je da je prvi bit 1. Ko bereš pol prebereš najprej size, iz katerega ugotoviš, da moraš prebrati 2 bajta. Najprej naredi resize vectorja na 16, kopiraš memory, pol pa resize na 9. Ampak premisli, če lahko rešiš elegantneje - tole je namreč malce grd "hack".

c0dehunter ::

mn, pametna ideja(drugi del), hvala :)

Kar se tiče prvega dela(zapis vectorja v datoteko) sem ugotovil da se v datoteko zmeraj zapiše ista vrednost(08, hex), ne glede na to kaj je dejansko v vectorju. Uporabljam kodo, ki si jo zapisal v prejšnjem postu. Sedaj sem sicer našel boost::dynamic_bitset, ki bo, zgleda, najbolj ustrezen..
I do not agree with what you have to say,
but I'll defend to the death your right to say it.

Ktj ::

Kaj pa če bi shranil v vektor po kjer več bitov predstavlja en vnos v vektor? Sicer nekaj dela bi bilo da bi jih primerno nastavil vendar potem z zapisovanjem neboš imel težave.

recimo:
 skupek_bitov[i/sizeof(tip_spremenljivke)] |= (izhod[i] & 1) << i%sizeof(tip_spremenljivke)



To je zgolj moja ideja pa še ta je v čisti smeri C-ja narejena.

mn ::

BTW, ker me je zanimalo zakaj prvi del ne dela sem si stvar malce podrobneje pogledal. V bistvu je logično da ne dela, ker operator[] pri bool vectorju ne vrača reference na objekt v bufferju ampak samo referenco na neko interno variablo. Ravno tako je logično da niti ne more vračati reference na sam objekt ker je nemogoče vrniti referenco na en sam bit! Se mi pa zdi zanimivo, da so se sploh odločili implementirati bool vector, ker podrejo cel kup garancij ki jih imaš pri vectorju.
Kakorkoli pravilno si se odločil, da si šel na boost::dynamic_bitset :)


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

[C] malloc, sigsegv

Oddelek: Programiranje
61051 (853) Andrej4
»

vector::iterator problemi, brisanje podatkov iz vektorja

Oddelek: Programiranje
81121 (972) mn
»

[cpp]Kako ugotoviti koliko zapisov je v arrayu?

Oddelek: Programiranje
6827 (746) technolog
»

C++(bin file) vprašanje

Oddelek: Programiranje
121496 (1374) technolog
»

Vodenje videoteke v C++

Oddelek: Programiranje
51776 (1596) Tutankhamun

Več podobnih tem