C-用十六进制打印出一个字符指针会给我带来奇怪的结果



所以我正在写一个非常小而简单的程序,它以数字为输入,将其转换为十六进制,并一次打印出两个字符。

对于某些数字,它会在输出前打印出ffffff。

这是我的代码:

    //Convert the input to an unsigned int
unsigned int a = strtoul (argv[1], NULL, 0);
//Convert the unsigned int to a char pointer
char* c = (char*) &a;
//Print out the char two at a time
for(int i = 0; i < 4; i++){
    printf("%02x ", c[i]);
}

大部分输出都很好,看起来像这样:

./hex_int 1
01 00 00 00

但对于一些数字,输出看起来是这样的:

./hex_int 100000
ffffffa0 ffffff86 01 00

如果你去掉所有的f,转换是正确的,但我不明白为什么它只在一些输入上这样做。

有人有什么想法吗?

您的参数和打印格式不匹配。默认参数promotions会将char参数(c[i])提升为int,该符号扩展(显然char是一个签名类型)。然后,您告诉printf使用%x格式将该参数解释为unsigned int。动臂-未定义的行为。

用途:

printf("%02x ", (unsigned int)(unsigned char)c[i]);

相反。

默认情况下,

char在您的系统上签名。将int移到其中会使编译器认为您希望在需要转换为int的操作中使用最高位作为符号位。将其打印为十六进制数就是一。

将字符指针c设置为unsigned char *,问题就会消失。

如果Carl的评论是正确的(我要检查一下),请使用这种故障保护方法:

printf("%02x ", c[i] & 0xff);

我在那里做了一段时间,我意识到,你可以在一个进程中看到exe映像,使用调试器,代码是可以的,但我暂时不能将这段机器代码传递给汇编程序,但好吧,有了指针,就一切皆有可能

include stdio.h
include windows.h
int main ()
{
int i=0;
char * p = (char *)0x400000;
for(int i = 0; i < 20; i++)
{
    printf("%p %02x n",p+i, (unsigned int)(unsigned char)*(p+i));
}
}

好吧,添加windows.h是为了使用一些系统调用,我在示例中省略了这些,因为没有必要使用下面代码中的那些,关于unsigned,是的,它可以被提交,因为char总是>0,关于地址,如前所述,0400000是exe的头,在这种情况下是"mz"头,但进程的dll代码可能是7c911000,和dll的头另一个地址,等等。。,这个信息在exe文件中,必须读取才能知道加载的图像在主内存中的加载位置,但当你只有一个进程时,如果你有更多的进程,你必须使用系统调用来知道第二个进程在哪里,如果一个地址不可读,只需在记事本中读取de.exe,该地址只是的一个示例

最新更新