0

Hello I am trying to write 8 bits from std::vector to binary file and read them back . Writing works fine , have checked with binary editor and all values are correct , but once I try to read I got bad data . Data that i am writing :

11000111 //bits

Data that i got from reading:

11111111 //bits

Read function :

std::vector<bool> Read()
{
    std::vector<bool> map;
    std::ifstream fin("test.bin", std::ios::binary);
    int size = 8 / 8.0f;
    char * buffer = new char[size];
    fin.read(buffer, size);
    fin.close();
    for (int i = 0; i < size; i++)
    {
        for (int id = 0; id < 8; id++)
        {
            map.emplace_back(buffer[i] << id);
        }
    }
    delete[] buffer;
    return map;
}

Write function(just so you guys know more whats going on)

void Write(std::vector<bool>& map) 
{
    std::ofstream fout("test.bin", std::ios::binary);
    char byte = 0;
    int byte_index = 0;
    for (size_t i = 0; i < map.size(); i++)
    {
        if (map[i]) 
        {
            byte |= (1 << byte_index);
        }
        byte_index++;
        if (byte_index > 7)
        {
            byte_index = 0;
            fout.write(&byte, sizeof(byte));
        }
    }
    fout.close();
}
9
  • 11
    int size = 8 / 8.0f; -- the mind boggles. Commented Jan 25, 2017 at 20:46
  • 1
    Not sure why you're using a fixed-size character buffer, especially one that's...a single byte long? Maybe? Are you expecting the file to contain 7.3 bits in the future? Commented Jan 25, 2017 at 20:48
  • 2
    vector <bool> is not exactly the greatest thing to use for any purpose Commented Jan 25, 2017 at 20:48
  • 6
    a "std::vector" with the variable name "map" is basically asking your coworkers to hate you Commented Jan 25, 2017 at 20:49
  • 1
    There's literally no reason to divide by a float. Also assumptions like #2 are how you get cripplingly bad overflow bugs. You can design around those assumptions, but always handle exceptional cases. Commented Jan 25, 2017 at 20:53

1 Answer 1

3

Your code spreads out one byte (the value of buffer[i], where i is always 0) over 8 bools. Since you only read one byte, which happens to be non-zero, you now end up with 8 trues (since any non-zero integer converts to true).

Instead of spreading one value out, you probably want to split one value into its constituent bits:

for (int id = 0; id < 8; id++)
{
    map.emplace_back((static_cast<unsigned char>(buffer[i]) & (1U << id)) >> id);
}
Sign up to request clarification or add additional context in comments.

9 Comments

thats because i pack 8 bits into one byte when was writing data to file
@EgiDijus: So you also need to split your one byte back out into eight bits. I added some code.
thats what i am trying to do when reading into loops buffer[i] << id , bit shifting byte to get 8 bits
@EgiDijus: Shifting isn't enough. You also need to mask out the unwanted bits.
Kerrek is right. Aside from the unsigned issues (never shift signed values), if you take 3 and shift it left by 1 you get a true value, shift it by 2 you still get a true value, etc. even though only the lower two bits are set.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.