C 在结构变量中写入一个字节

C 在结构变量中写入一个字节,c,C,我正试图用以下代码修改结构的一个字节: struct example *dev; PRINT_OPAQUE_STRUCT(dev); sprintf((char*) dev + 24, "%x",1); PRINT_OPAQUE_STRUCT(dev); PRINT_不透明_结构只是打印结构的内容,在另一个主题中定义: 该程序的输出为: D046F64F20B3FB4F00000000E047F64F00000000FFFFFF000000 D046F64F20B3FB4F00000000

我正试图用以下代码修改结构的一个字节:

struct example *dev;

PRINT_OPAQUE_STRUCT(dev);
sprintf((char*) dev + 24, "%x",1);
PRINT_OPAQUE_STRUCT(dev);
PRINT_不透明_结构只是打印结构的内容,在另一个主题中定义:

该程序的输出为:

D046F64F20B3FB4F00000000E047F64F00000000FFFFFF000000 D046F64F20B3FB4F00000000E047F64F00000000FFFFFF310000

我不知道为什么我写了值“31”,而不是想要的值“01”。我试图用“%01x”替换sprintf的第二个参数,但它没有改变任何东西。有人知道为什么吗


谢谢

嗯,您正在将值
1
格式化为字符串。这就是sprintf所做的
0x31
是字符
'1'
的字符代码。如果只想将字节值
0x01
写入结构,则不需要
sprintf
。只要这样做:

*((char*)dev + 24) = 1;
或者(相同,但语法略有不同):


另外请注意,如所说,
sprintf
将不会只写入一个字节。由于它写入一个字符串,并且C字符串以null结尾,因此它还将在
'1'

之后写入一个空字符(
'\0'
0x00
)。这就是sprintf所做的
0x31
是字符
'1'
的字符代码。如果只想将字节值
0x01
写入结构,则不需要
sprintf
。只要这样做:

*((char*)dev + 24) = 1;
或者(相同,但语法略有不同):

另外请注意,如所说,
sprintf
将不会只写入一个字节。由于它写入一个字符串,并且C字符串以null结尾,因此它还将在
'1'
之后写入一个空字符(
'\0'
0x00

我不知道为什么我写了值“31”,而不是想要的值“01”

您看到
31
的原因是您的函数链将值
1
解释了两次:

  • 首先,
    sprintf
    将其解释为代表十六进制数字的字符
  • 其次,
    PRINT\u OPAQUE\u STRUCT
    再次将值解释为十六进制数
本质上,
sprintf
1
转换为其字符表示形式,即
'1'
。在您的系统上,它的代码是
0x31
,因此您可以得到输出

您需要删除这两种解释中的一种,才能让代码打印
1
。要删除第一个解释,只需将
1
分配给指针,如下所示:

((char*)dev)[24] = 1;
要删除第二种解释,请使用
%c
而不是
打印不透明结构中的
%x
进行打印(这可能不可能)

我不知道为什么我写了值“31”,而不是想要的值“01”

您看到
31
的原因是您的函数链将值
1
解释了两次:

  • 首先,
    sprintf
    将其解释为代表十六进制数字的字符
  • 其次,
    PRINT\u OPAQUE\u STRUCT
    再次将值解释为十六进制数
本质上,
sprintf
1
转换为其字符表示形式,即
'1'
。在您的系统上,它的代码是
0x31
,因此您可以得到输出

您需要删除这两种解释中的一种,才能让代码打印
1
。要删除第一个解释,只需将
1
分配给指针,如下所示:

((char*)dev)[24] = 1;

要删除第二种解释,请使用
%c
而不是
打印不透明结构中的
%x
(这可能是不可能的)。

此操作。加上打印出来的结构长度是54。除以2等于27。他正在修改为24,这就是为什么它减少了3个字节。另外,
sprintf
将向数组中写入一个
'\0'
字符串终止符,该数组恰好已经在该位置包含
'\0'
。这是。加上打印出来的结构长度是54。除以2等于27。他正在修改为24,这就是为什么它减少了3个字节。另外,
sprintf
将向数组中写入一个
'\0'
字符串终止符,该数组恰好在该位置包含
'\0'
。还要注意,您将要更改为00的字符后的字符更改为00。在这种情况下,它已经是00,所以你看不到它,但是如果它是,比如说,42,你会将它改写为00。另外请注意,你在你想要更改为00的字符之后更改了该字符。在这种情况下,它已经是00,所以你看不到它,但是如果它是,比如说,42,你会将它覆盖到00