【问题标题】:Hex Dump Utility C++ Displaying Hex and Ascii十六进制转储实用程序 C++ 显示 Hex 和 Ascii
【发布时间】:2014-05-23 00:09:03
【问题描述】:

好的,所以我调用 read file 来填充 slop 槽,但它仅适用于 .txt 或 .bin 文件,当我打开其他任何文件时崩溃,例如 .doc 文件 错误代码0xC0000005:访问冲突执行位置0xFFFFFFFF。

这也是显示文件的十六进制和 ascii 转储的正确方法吗?

//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];
}
}

【问题讨论】:

  • sizeof(slop_trough) * MAX 这将读取sizeof(unsigned char*) * MAX 字符,通常是缓冲区实际大小的 4 到 8 倍。
  • 如果文件短于MAX字节怎么办?为什么要将数组的大小乘以MAX
  • @user657267 slop_trough 是一个数组,而不是一个指针。所以它实际上会读取MAX * MAX 字节。数组在sizeof 中使用时不会衰减为指针。
  • 函数中的@Barmar slop_trough 是一个指向unsigned char 的指针,不要让[] 语法欺骗了你。
  • 哎呀,你是对的,没有注意到它是一个函数参数以及一个全局变量。使用相同的变量名是另一种不好的做法。

标签: c++ hex ascii dump utility


【解决方案1】:

试试这样的:

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 );
}

查看此示例以获得更强大的十六进制查看器实现:

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

【讨论】:

  • 哇,谢谢雷米!我在读取一些二进制文件时遇到问题,它一直找不到它们,并且 slop_ptr 未定义我真的不知道它做了什么,所以我把它注释掉了。
  • slop_ptr 应改为 slop。我已经纠正了。至于打开文件,您有责任确保提供正确的filenameReadFile()
  • 不错。我只是从用户那里得到一个字符串并将其传递给 ReadFile() 而不带引号!非常感谢,我真的很感激,有一天我可以回馈给 SO
猜你喜欢
  • 2011-08-02
  • 1970-01-01
  • 2011-12-09
  • 2015-05-22
  • 1970-01-01
  • 2013-05-24
  • 2013-10-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多