首页 > 解决方案 > 将十六进制值设置为 char 变量以进行填充的问题

问题描述

我在尝试将char变量设置为十六进制值时遇到问题。

我正在尝试实现打印功能,在其中打印结构的对齐方式。“aa”应该代表填充,但我似乎无法在默认构造函数中设置变量。

应该是的输出

0x00: 00 00 00 00      
0x04: 00 aa aa aa 

.h 文件

struct A
{
    int  a0;
    char a1;
    char pad0;
    char pad1;
    char pad2;
    A() {
        a0 = 0;
        a1 = 0;
        pad1 = 0xAA;
        pad2 = 0xAA;
    }
};

.cpp


Alignment::Alignment:Print(void *data)  
{
    int d {0 };
    for (int i = 0; i <2; ++i) {
        printf("\n0x%02x:", (d));
        d = d + 4;
        for (int j = 0; j < sizeof(data); ++j)
        {
            printf(" %.2x", (*((unsigned char*)data+j )));
        }
     }

}

主要的

A *pa = new A;

Pa 被传递到函数中

我的输出

0x00: 00 00 00 00
0x04: 00 00 00 00

标签: c++databasedata-structuresalignmentpadding

解决方案


Print您的功能存在一些问题。有些是“公正”的风格,但它们使解决真正问题变得更加困难。(另外,你草率下结论,可能让你对真正的问题视而不见。)首先,试着解释为什么这条线

            printf(" %.2x", (*((unsigned char*)data+j )));

应该做一些不同的事情只是因为id改变。这些变量都不在这一行中,因此每次外循环迭代都会得到相同的输出。问题不在于数据的设置,而在于数据的读取。对于每一行输出,当您打算打印接下来的四个字节时,您打印前四个字节的数据。

要获取接下来的四个字节,您需要添加d指针,但这是有问题的,因为您d在此迭代的早期增加了。最好d在每次迭代中保持相同的值。您可以在迭代结束而不是中间增加它,但甚至更光滑可能d用于控制循环而不是i.

最后,一点鲁棒性:您的代码4在增加 时使用幻数d,仅当sizeof(data)为 4 时才有效。易碎。最好为这个魔法值使用一个符号常量来确保一致性。我将其明确设置为,4因为我不明白为什么指针的大小会影响指向数据的显示方式。

Alignment::Alignment::Print(void *data)  
{
    constexpr int BytesPerLine = 4; // could use sizeof(void *) instead of 4
    const unsigned char * bytes = static_cast<unsigned char*>(data); // Taking the conversion out of the loop.

    for (int d = 0; d < 2*BytesPerLine; d += BytesPerLine) {
        printf("\n0x%02x:", (d));
        for (int j = 0; j < BytesPerLine; ++j)
        {
            printf(" %.2x", *(bytes + d + j)); // Add d here!
        }
     }
}

推荐阅读