C语言 如何获取结构数据的十六进制转储
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7775991/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to get hexdump of a structure data
提问by Udit Gupta
....
finalize(char *hdrs, sendip_data *headers[], int index,
sendip_data *data, sendip_data *pack)
{
........
For debugging purposes I want a hex dump of the dataand packstructures, which are of type sendip_data, a really complex structure. Actually they contain some binary information so I am not sure whether output of my project is correct or not. So for debugging purposes, I want to write the data into a file so that I can use hexdump as follows -
出于调试目的,我想要一个data和pack结构的十六进制转储,它们的类型sendip_data是非常复杂的结构。实际上它们包含一些二进制信息,所以我不确定我的项目的输出是否正确。因此,出于调试目的,我想将数据写入文件,以便我可以按如下方式使用 hexdump -
$hexdump -C file.txt
Also as this is a run time generation of a n/w packet so I am also not sure about the length of dataand packstructure which I think fread / fwritewill require ..So please suggest me something.
此外,由于这是 an/w 数据包的运行时生成,所以我也不确定我认为需要的长度data和pack结构......fread / fwrite所以请给我建议。
回答by paxdiablo
The following code will give you a hex dump of arbitrary memory from within your code.
以下代码将从您的代码中为您提供任意内存的十六进制转储。
#include <stdio.h>
void hexDump (const char * desc, const void * addr, const int len) {
int i;
unsigned char buff[17];
const unsigned char * pc = (const unsigned char *)addr;
// Output description if given.
if (desc != NULL)
printf ("%s:\n", desc);
// Length checks.
if (len == 0) {
printf(" ZERO LENGTH\n");
return;
}
else if (len < 0) {
printf(" NEGATIVE LENGTH: %d\n", len);
return;
}
// Process every byte in the data.
for (i = 0; i < len; i++) {
// Multiple of 16 means new line (with line offset).
if ((i % 16) == 0) {
// Don't print ASCII buffer for the "zeroth" line.
if (i != 0)
printf (" %s\n", buff);
// Output the offset.
printf (" %04x ", i);
}
// Now the hex code for the specific character.
printf (" %02x", pc[i]);
// And buffer a printable ASCII character for later.
if ((pc[i] < 0x20) || (pc[i] > 0x7e)) // isprint() may be better.
buff[i % 16] = '.';
else
buff[i % 16] = pc[i];
buff[(i % 16) + 1] = 'my_str:
0000 61 20 63 68 61 72 20 73 74 72 69 6e 67 20 67 72 a char string gr
0010 65 61 74 65 72 20 74 68 61 6e 20 31 36 20 63 68 eater than 16 ch
0020 61 72 73 00 ars.
';
}
// Pad out last line if not exactly 16 characters.
while ((i % 16) != 0) {
printf (" ");
i++;
}
// And print the final ASCII buffer.
printf (" %s\n", buff);
}
// Very simple test harness.
int main (int argc, char *argv[]) {
char my_str[] = "a char string greater than 16 chars";
hexDump ("my_str", &my_str, sizeof (my_str));
return 0;
}
You pass into hexDumpa description, memory address and length, and it will output a hex dump (including character data) for examination. When you run it with the included main, the output is:
你传入hexDump一个描述、内存地址和长度,它会输出一个十六进制转储(包括字符数据)以供检查。当您使用包含的 运行它时main,输出为:
// Android logging
#include <android/log.h>
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , "~~~~~~", __VA_ARGS__)
#define DLOG(...) __android_log_print(ANDROID_LOG_DEBUG , "~~~~~~", __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , "~~~~~~", __VA_ARGS__)
#define ELOG(...) __android_log_print(ANDROID_LOG_ERROR , "~~~~~~", __VA_ARGS__)
#ifdef __cplusplus
extern "C" {
#endif
void log_dump(const void*addr,int len,int linelen);
void log_dumpf(const char*fmt,const void*addr,int len,int linelen);
#ifdef __cplusplus
}
#endif
回答by 18446744073709551615
A hex dump for Android, should be suitable for other platforms as well.
Android 的十六进制转储应该也适用于其他平台。
LOGD(), same as DLOG(), plays the role of printf()because printf()does not work in Android. For platforms other than Android, you may #define DLOG printf.
LOGD(), 与DLOG(), 的作用相同,printf()因为printf()在 Android 中不起作用。对于 Android 以外的平台,您可以#define DLOG printf.
dlog.h:
dlog.h:
#include <dlog.h>
//#include <alloca.h>
inline char hdigit(int n){return "0123456789abcdef"[n&0xf];};
#define LEN_LIMIT 8
#define SUBSTITUTE_CHAR '`'
static const char* dumpline(char*dest, int linelen, const char*src, const char*srcend)
{
if(src>=srcend) {
return 0;
}
int i;
unsigned long s = (unsigned long)src;
for(i=0; i<8; i++) {
dest[i] = hdigit(s>>(28-i*4));
}
dest[8] = ' ';
dest += 9;
for(i=0; i<linelen/4 ; i++) {
if(src+i<srcend) {
dest[i*3] = hdigit(src[i]>>4);
dest[i*3+1] = hdigit(src[i]);
dest[i*3+2] = ' ';
dest[linelen/4*3+i] = src[i] >= ' ' && src[i] < 0x7f ? src[i] : SUBSTITUTE_CHAR;
}else{
dest[i*3] = dest[i*3+1] = dest[i*3+2] = dest[linelen/4*3+i] = ' ';
}
}
return src+i;
}
void log_dumpf(const char*fmt,const void*addr,int len,int linelen)
{
#if LEN_LIMIT
if(len>linelen*LEN_LIMIT) {
len=linelen*LEN_LIMIT;
}
#endif
linelen *= 4;
static char _buf[4096];
char*buf = _buf;//(char*)alloca(linelen+1); // alloca() causes the initialization to fail!!!!
buf[linelen]=0;
const char*start = (char*)addr;
const char*cur = start;
const char*end = start+len;
while(!!(cur = dumpline(buf,linelen,cur,start+len))){DLOG(fmt,buf);}
}
void log_dump(const void*addr,int len,int linelen)
{
log_dumpf("%s\n",addr,len,linelen);
}
dump.cpp:
转储.cpp:
log_dumpf("args: %s\n", &p, 0x20, 0x10);
Usage example:
用法示例:
args: 61efadc4 00 3c 17 01 6d bc 59 61 02 00 00 00 80 ae ef 61 `<``m`Ya```````a
args: 61efadd4 00 3c 17 01 00 00 00 00 31 a5 59 61 80 ae ef 61 `<``````1`Ya```a
Output:
输出:
##代码##UPDATE:see dump.cppand re_dump.hin reDroid (github), it includes a recursive dump that checks if a pointer is valid.
更新:看到dump.cpp和re_dump.h在reDroid(github上),它包括:一个递归转储检查是否一个指针是有效的。

