【问题标题】:Preforming manipulations on C memory addresses as char* to output.将 C 内存地址上的操作作为 char* 进行输出。
【发布时间】:2017-10-06 18:42:48
【问题描述】:

我正在尝试将 argv 中所有参数的地址打印为分段字符。

argv[0]的地址

0x7ffdf0451078

我想把它打印成

0x7ffd f0 45 10 78

然后截断开始的id,并将其打印成类似于

的格式化网格
 +------+------+------+------+
 |  f0  |  45  |  10  |  78  | 
 +------+------+------+------+

我假设完成此操作的最简单方法是将 argv[0] 的地址保存为字符串或 char 数组,然后对该字符串/数组进行一些操作。

但是,到目前为止,我还无法将地址放入任何类型的容器中。

【问题讨论】:

标签: c


【解决方案1】:

你可以的

char str[100];
sprintf(str, "%p", argv[0]);

如果argv[0]0x7ffdf0451078,现在str 将有"0x7ffdf0451078"

您只需要f0451078 部分。即str+6 部分。

现在使用sscanf() 喜欢

char d[4][3];
sscanf(str+6, "%2s%2s%2s%2s", d[0], d[1], d[2], d[3]);

并根据需要打印它们。

如果您使用%x 格式说明符而不是%p,请使用str+4

演示here.

【讨论】:

  • 啊,是的,这看起来工作正常。对于sscanf(str+4, "%2s%2s%2s%2s", d[0], d[1], d[2], d[3]);,它应该是+6,否则它会抓取不正确的地址部分。
【解决方案2】:
void *ptr = argv[0];
printf("%02x %02x %02x %02x\n",
       (int)((ptr / 0x1000000) & 0xff),
       (int)((ptr / 0x10000) & 0xff),
       (int)((ptr / 0x100) & 0xff),
       (int)(ptr & 0xff));

【讨论】:

  • 我看到你在这个细分中做了什么,但是它给了我每个细分的错误error: invalid operands of types ‘void*’ and ‘int’ to binary ‘operator/’ (int)((ptr / 0x100) & 0xff),
【解决方案3】:

如果您想控制指针的表示,您可能希望将其转换为intptr_t,以便您对printf 样式说明符的行为有信心。 (%p的输出格式是实现定义的。)

#include <stdio.h>
#include <inttypes.h>

int main(int argc, char *argv[])
{
    intptr_t address = (intptr_t) &argv[0];

    char repr[1 + 2*sizeof(intptr_t)]; // 2 chars per byte plus a '\0'
    snprintf(repr, sizeof repr, "%" PRIxPTR, address); // this is the magic

    printf("0x%.4s %.2s %.2s %.2s %.2s\n", repr, repr+4, repr+6, repr+8, repr+10);
    // output: 0x7ffd f0 45 10 78

    printf("+------+------+------+------+\n");
    printf("|  %.2s  |  %.2s  |  %.2s  |  %.2s  |\n", repr+4, repr+6, repr+8, repr+10);
    printf("+------+------+------+------+\n");
    // output:
    // +------+------+------+------+
    // |  f0  |  45  |  10  |  78  | 
    // +------+------+------+------+
}

我发现this question 用于格式化intptr_t,我使用%s 格式说明符的精度字段来打印snprintf 创建的字符串部分。

虽然repr 的大小是根据sizeof(intptr_t) 定义的,但这里的打印代码假定为24 位地址。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-08
    • 2019-03-22
    • 1970-01-01
    • 2012-10-29
    • 2010-12-31
    • 1970-01-01
    • 2020-07-18
    相关资源
    最近更新 更多