【问题标题】:Print the value of a pointer in hex format without printf在没有 printf 的情况下以十六进制格式打印指针的值
【发布时间】:2020-08-14 13:05:39
【问题描述】:

如何将void *指针转换为char *,以便我可以以十六进制格式打印存储在ptr中的地址?没有printf()

#include<stdio.h>

int main()
{
    int a=5;
    void *ptr=&a;
    char *arr=(char*)ptr;
    write(1,arr,strlen(arr));

    return 0;
}

【问题讨论】:

  • 您认为为什么需要将其转换为打印?也就是说,您的问题真的是“如何打印指针值”还是确实是“如何将 void * 转换为 char *”? “不打印”是什么意思?
  • 对不起,我想我明白你的意思了。 char * 是指将指针值转换为字符串吗?
  • 你的问题不是很清楚。无论如何,要以十六进制打印任何内容,您不需要write,它只写入原始字节,但您需要printf。我认为在您的情况下,您只需要 printf("%p\n", &amp;a) 打印变量 a 的地址。
  • @Jabberwocky 出于某种原因,OP 希望它“不打印”。我猜这意味着 OP 想要手动将指针转换为字符串表示形式。
  • @Nurdaulet_mit22 计算机不存储十六进制数字。他们只是存储数字。这些数字可以用十进制、十六进制、八进制等表示。您可能应该回到基础。

标签: c pointers memory-address


【解决方案1】:

如果您没有可用的printf(),则需要手动转换该值,然后将其写出。以下示例假设您的系统是小端(如果是大端,只需反转 for 循环)。请参阅Detecting Endianness 了解更多信息。

void *ptr = &a;
unsigned char buf[sizeof(ptr)];

memcpy(buf, &ptr, sizeof(ptr));

for (int i = sizeof(ptr) - 1; i >= 0; i--) {
    unsigned char hi = (buf[i] >> 4) & 0xf; 
    unsigned char lo = buf[i] & 0xf;        
    char tmp[2] = {hi, lo};

    tmp[0] += hi < 10 ? '0' : 'a' - 10;
    tmp[1] += lo < 10 ? '0' : 'a' - 10;

    write(1, tmp, 2);
}

结果:

00007fffa6cf0f64

【讨论】:

  • 我和 op 有同样的问题。扭曲是我每个函数限制为 25 行,并且不能使用三元组。我试图转换你的代码,但它打印为 \x1f\xefO\x1f\x7fO\xaf\x7f\xdf\xaf\x0f\xdf?6of 你能帮帮我吗?
  • @MiguelM 我无法在我的另一个答案的评论部分为您提供帮助。发布一个新问题,如果你觉得它会是一个体面的问题。这不是一个编程代码高尔夫网站(例如Code Golf SE),所以请记住这一点。
【解决方案2】:

指针的指向类型与你要打印的值指针无关。如果要将值指针打印为数字(例如,该值存储在内存中的地址),则必须首先将该指针转换为整数,以便可以使用数字打印方法。这是在printf(3) 函数中完成的,当您使用%p 格式说明符指定格式中的指针值(无论它指向什么类型)时。

#include<stdio.h>

int main()
{
    int a=5;

    printf("The address   of a is: %p\n", &a);
    printf("and the value of a is: %d\n", a);

    return 0;
}

在执行时,你会得到类似这样的东西:

$ pru
The address   of a is: 0x7fffffffe3bc
and the value of a is: 5
$ _

【讨论】:

    【解决方案3】:

    您要查找的函数称为 sprintf。它以您指定的格式生成其参数的文本表示(字符)。

    #include<stdio.h>
    #include<stdio.h>
    
    int main()
    {
        int a = 5; // okay
        void *ptr = &a; // okay
    
        // conversion works only for between basic types (one number to another)
        // but not for a text (human-readable hexadecimal representation)
        //char *arr = (char*)ptr;
    
        // need enough memory for storing the hexadecimal text representation including 0 value at the end, we are using 20 bytes here
        char arr[20];
    
        // write the pointer as hexadecimal
        // depending on your architecture (32 bit / 64 bit), one of the following lines could work
        // %x writes an unsigned int, %lx an long unsigned int
        sprintf(arr, "%x", (unsigned int)ptr);        
        sprintf(arr, "%lx", (long unsigned int)ptr);
    
        // some systems have the secure variant sprintf_s, where you also give the length of your array arr as parameter (here: 20) to make sure it does not write over the end
    
        // for testing, write out the arr on screen (as %s = string)
        printf("%s\n", arr);
        //write(1,arr,strlen(arr));
    
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-12
      • 2013-01-21
      • 1970-01-01
      • 2020-05-14
      • 2021-04-21
      • 1970-01-01
      • 2019-01-29
      • 1970-01-01
      相关资源
      最近更新 更多