Search code examples
c++debuggingbinaryfiles

Bug with writing bitset to file


I have this function for a compression assignment (due 2 days ago, I'm just trying to find out what went wrong).

It's supposed to print out to stdout the output or write it to file. The stdout output is 100% accurate.

However, the binary writing always produces garbage. E.g. it's supposed to be 23 bytes of output, but is always 16 bytes, and isn't anything like what it's supposed to be. I've stared at this for 2 hours, could anyone provide a hint as to what's wrong?

Thank you so much.

void writer(char character, int count,std::string outputpath){
    if(outputpath == "cout"){
        switch(count){
            case 1:{
                std::cout << character;
                break;
            }
            case 2:{
                std::cout << character<< character;
                break;
            }
            default:{
                std::cout << character;
                auto output = conversion(count);
                for(auto i: *output){
                    std::cout << i;
                }
            }
        }
    }else{

        std::vector<std::bitset<8>> source;
        std::bitset<8>temp(character);
        switch(count){
            case 1:{
                source.push_back(temp);
                break;
            }
            case 2:{
                source.push_back(temp);
                source.push_back(temp);
                break;
            }
            default:{
                source.push_back(temp);
                auto output = conversion(count);
                for(auto i: *output){
                    source.push_back(i);
                }
            }
        }

        //write
        {
            std::ofstream file( outputpath, std::ios::binary ) ; // output file stream

            // write the contents of the vector to the file
            for( auto i : source ){
                file.write( reinterpret_cast<const char*>( &i ), 8 ) ;
            }
        }
    }
}

Solution

  • file.write( reinterpret_cast<const char*>( &i ), 8 ) ;
    

    The second parameter to write() is the number of characters that will be written. &i is the location of a 8 bit bitset.

    All the other problems with your source aside (for which you should perhaps go to codereview.SE), that should be a 1, not a 8.

    Also, on every call to writer(), you re-open the output file, overwriting its contents in the process.


    You didn't show us the calling code. But with a simple tweak, you could've made the (reportedly fully functional) std::cout code work for files as well -- by passing std::ostream & instead of a filename to the function, and leave it to the caller whether to invoke writer() with std::cout or opening outputpath:

    void writer( char character, int count, std::ostream & out )
    {
        switch( count )
        {
            case 1:
            {
                out << character;
                break;
            }
            case 2:
            {
                out << character << character;
                break;
            }
            default:
            {
                out << character;
                auto output = conversion( count );
                for ( auto i: *output )
                {
                    out << i;
                }
            }
        }
    }
    

    Calling for std::cout output:

    writer( character, count, std::cout );
    

    Calling for file output:

    std::ofstream file( outputpath, std::ios::binary );
    // ...
    writer( character, count, file );