简体   繁体   中英

C - Printing out a char pointer in hex is giving me strange results

So I am writing a very small and simple program which takes a number as input, converts it to hex, and prints it out two characters at a time.

For some numbers, it prints out ffffff in front of the output.

This is my code:

    //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]);
}

Most of the output is fine and looks like this:

./hex_int 1

01 00 00 00

But for some numbers the output looks like this:

./hex_int 100000

ffffffa0 ffffff86 01 00

If you remove all the f's the conversion is correct, but I cannot figure out why it is doing this only on some inputs.

Anyone have any ideas?

You're mismatching parameters and print formats. The default argument promotions cause your char parameter ( c[i] ) to be promoted to int , which sign extends (apparently your char is a signed type). Then you told printf to interpret that argument as unsigned int by using the %x format. Boom - undefined behaviour.

Use:

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

Instead.

char is, by default, signed on your system. Moving an int into it makes your compiler think you want to use the highest bit as sign bit on operations that needs to be cast to an int. And printing it as a hex number is one.

Make the char pointer c an unsigned char * and the problem will go away.

If Carl is right with his comment (I'm going to check), use this fail-safe method instead:

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

I where doing this for a while and i realize, you can see the exe image in a process, use a debuger, the code is all right, but i cant for the moment to pass this machine code to assembler, but well, with a pointer all is possible

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,该地址只是一个例子

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM