Question

I have a C++ program that writes on a file (fstream) all the 'key' (char) and 'value' (int) from a 'map'. Then I close the stream, but when I read later this file , I notice that what it prints it's not what is in the file. Can you help me finding thw problem? Thanks!

Here is the code:

void Encoder::get_freq_tab()
{
map<unsigned char,int>::iterator it;
int next=0;
while((next = text.get()) != EOF)
{
    unsigned char uc = unsigned char(next);
    it=char_freq.find(uc);
    if(it!=char_freq.end())
        ++(it->second);
    else
        char_freq.insert(make_pair(uc,1));
}
text.clear();
}


void Encoder::write_h_code(string s)
{
    out.open(&s[0],ios::out | ios::binary);
    string code;
    char c;
    unsigned char acc=0;
    int bit,bitpos=0,cont,n;
    cont=mytree.get_tree_freq();    
    map<unsigned char, int>::iterator it;
    out<<unsigned char(char_freq.size());
    cout<<"ENCODER number of chars = "<<int(char_freq.size())<<endl;
        for(it=char_freq.begin();it!=char_freq.end();++it)
{
    c=((*it).first);
    n=(*it).second;     
    out<<unsigned char(c);
    out<<int(n);
    cout<<"ENCODER wrote "<<int(c)<<" .Size = "<<sizeof(c)<<" .Freq = "<<n<<" . Size = "<<sizeof(n)<<endl;
}
}

This part is only about the reading the bytes from the file, storing the frequencies in the map char_freq, and writing, first the number of the char stored, and then all the keys and values. Now the part where it reads back this file.

void Decoder::extract_leaves(){
unsigned char c,tot;
int n,size;
in>>(tot);  // set size, per controllare il limite delle foglie
size=(tot);
cout<<endl<<"DECODER number of char = "<<size<<endl;
for(int i=0;i<size;++i)
    {
    in>>unsigned char(c);   // reading char 
    in>>int(n);     // reading frequence
    cout<<" Decoder Val "<<int(c)<<" Freq = "<<int(n)<<endl;
    }

}

When I print and read the same file, I see other freq values, like it writes more bytes for a int, and so some values doesn't appear as it "jumps" over them when reading.

Était-ce utile?

La solution

When writing binary data, you can not use in >> x or out << x, since those are "text read and write" functions.

So, instead of:

out<<unsigned char(c);
out<<int(n);

you will need to use:

out.write(&c, sizeof(c));
out.write(reinterpret_cast<char*>(&n), sizeof(n));

To explain in more detail:

n = 12345;
out << n; 

will output 12345 as individual characters.

If you output this:

c = '1';
n = 2345;
out << c << n;

then the output will also look like 12345.

On the other hand, in >> c will skip spaces, so

c = ' ';
n = 1234;
out << c << n;

in >> c >> n; 

will have c == '1' and n==234 after the input.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top