【问题标题】:Writing one byte in struct variable在结构变量中写入一个字节
【发布时间】:2017-04-13 18:15:54
【问题描述】:

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

struct example *dev;

PRINT_OPAQUE_STRUCT(dev);
sprintf((char*) dev + 24, "%x",1);
PRINT_OPAQUE_STRUCT(dev);

PRINT_OPAQUE_STRUCT 只是打印结构的内容,并在另一个主题中定义: Print a struct in C

这个程序的输出是:

d046f64f20b3fb4f00000000e047f64f00000000ffffffff000000 d046f64f20b3fb4f00000000e047f64f00000000ffffffff310000

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

谢谢!

【问题讨论】:

  • 还请注意,您将要更改的字符后面的字符更改为 00。在这种情况下,它已经是 00,所以您看不到它,但如果是 42,您就会看到将其覆盖为 00

标签: c


【解决方案1】:

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

*((char*)dev + 24) = 1;

或(相同,但语法略有不同):

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

还要注意,就像one comment below 所说,sprintf 不会只写一个字节。由于它写入的是一个字符串,而 C 字符串是以 null 结尾的,所以它还会在 '1' 之后写入一个 null 字符('\0'0x00)。

【讨论】:

  • 这个。加上打印出来的结构长度是 54。除以 2,是 27。他正在修改为 24,这就是为什么它少了 3 个字节。
  • 加上sprintf 将在数组中写入一个'\0' 字符串终止符,该数组恰好在该位置已经包含'\0'
【解决方案2】:

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

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

  • 首先,sprintf 将其解释为代表十六进制数字的字符
  • 其次,PRINT_OPAQUE_STRUCT 再次解释该值,现在为十六进制数

本质上,sprintf1 转换为其字符表示形式,即'1'。在你的系统上,它的代码是0x31,因此你得到了输出。

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多