将十六进制值设置为 char 变量以进行填充时出现问题

Posted

技术标签:

【中文标题】将十六进制值设置为 char 变量以进行填充时出现问题【英文标题】:Issues setting a hexadecimal value to a char variable for padding 【发布时间】:2020-05-11 08:23:51 【问题描述】:

我在尝试将 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

【问题讨论】:

您的预期结果是什么,您的打印效果如何? 你没有在你的构造函数中初始化pad0 @Chipster 我希望在检测到填充时打印 AA。但是,我确定如何将其设置为 char 变量。 您如何尝试打印。你能把它添加到你的问题中吗? @Chipster 是的,很抱歉我添加了它 【参考方案1】:

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

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

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

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

最后,一点稳健性:您的代码在增加d 时使用幻数4,这仅在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!
        
     

【讨论】:

如何让每个焊盘都显示为 aa 而不是 00? @Jay 设置为0xaa 的两个确实以aa 出现,一旦您将d 添加到您打印其内容的地址。见example on Wandbox。 每当我尝试将 pad 设置为 0xaa 并编译时,我都会发出警告,指出以下内容将被视为错误。我应该在设置时将字符垫设为无符号吗? @Jay 是的,unsigned 适用于被视为位模式而不是数字的值。

以上是关于将十六进制值设置为 char 变量以进行填充时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

将 char 2d 数组转换为 2d char 数组列表时出现问题

在 sparksql 中以正确格式将字符串数据转换为十进制时出现问题

char数组中的十六进制导致写入套接字时出现随机字符

将字符串变量分配给unsigned char变量

在 vb6 中填充组合框时出现运行时错误 0

当我尝试将函数的参数设置为默认值时出现意外错误