Search code examples
c++hexasciidumputility

Hex Dump Utility C++ Displaying Hex and Ascii


Alright so I call read file to fill up the slop trough but it only works with .txt or .bin files and crashes when I open anything else, such as .doc files with error code 0xC0000005: Access violation executing location 0xFFFFFFFF.

Also is this even the correct way to go about displaying to screen the hex and ascii dumps of a file?

//The slop_trough I dump all the hex and ascii slop into
unsigned char slop_trough [MAX] = {0} ;

void ReadFile (string filename, unsigned char slop_trough [])
{
ifstream open_bin;
open_bin.open(  filename, ios::in | ios::binary  ) ;
if ( open_bin.is_open() )
{
    open_bin.read ( reinterpret_cast <char *> (slop_trough),
        sizeof(slop_trough) * MAX ) ;

    open_bin.close();
}
else
    cout << "File not opened!" << endl;

}

void HexDump (unsigned char slop_trough [])
{
for ( int j = 0; j < MAX - 1; ++j)
{
   cout << hex << slop_trough[j] ;
}
}

void AsciiDump(unsigned char slop_trough [])
{
for ( int p = 0; p < MAX - 1; ++p)
{
   cout << slop_trough[p];
}
}

Solution

  • Try something like this:

    streamsize ReadFile (const string &filename, unsigned char *slop, int max_slop)
    {
        ifstream open_bin;
    
        open_bin.open( filename, ios::in | ios::binary  ) ;
        if ( !open_bin.is_open() )
        {
            cout << "File not opened! " << filename << endl;
            return 0;
        }
    
        if( !open_bin.read ( reinterpret_cast<char*>(slop), max_slop ) )
        {
            cout << "File not read! " << filename << endl;
            return 0;
        }
    
        return open_bin.gcount();
    }
    
    void HexDump (unsigned char *slop, streamsize slop_len)
    {
        for ( int j = 0; j < slop_len; ++j)
        {
            cout << noshowbase << hex << setw(2) << setfill('0') << slop[j] << ansi::reset();
            cout.put(' ');
        }
        cout << dec << setw(0) << setfill(' ');
    }
    
    void AsciiDump(unsigned char *slop, streamsize slop_len)
    {
        for ( int p = 0; p < slop_len; ++p)
        {
           if ( (slop[p] > 0x20) && (slop[p] < 0x7F) && (slop[p] != 0x0A) && (slop[p] != 0x0D) )
               cout << slop[p];
           else
               cout << '.';
        }
        cout << ansi::reset();
    }
    

    //The slop_trough I read the file data into
    unsigned char slop_trough [MAX] = {0} ;
    
    streamsize slop_len = ReadFile ( "filename", slop_trough, MAX );
    unsigned char *slop = slop_trough;
    
    while ( slop_len >= 16 )
    {
        HexDump ( slop, 16 );
        cout << "| "; 
        AsciiDump( slop, 16 );
        cout << endl;
    
        slop += 16;
        slop_len -= 16;
    }
    
    if ( slop_len > 0 )
    {
        HexDump ( slop, slop_len );
        cout << left << setw(48 - (slop_len * 3)) << setfill(' ') << "| ";
        AsciiDump( slop, slop_len );
    }
    

    Have a look at this example for a more robust hex viewer implementation:

    http://www.cplusplus.com/articles/NwTbqMoL/