将十六进制值设置为 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 )));
应该做一些不同的事情只是因为i
和d
发生了变化。这些变量都不在这一行中,因此每次外循环迭代都会得到相同的输出。问题不在于数据的设置,而在于数据的读取。对于每一行输出,当您打算打印接下来的四个字节时,您会打印前四个字节的数据。
要获取接下来的四个字节,您需要将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 数组列表时出现问题