Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defined behavior, passing character to printf("%02X"

I recently came across this question, where the OP was having issues printing the hexadecimal value of a variable. I believe the problem can be summed by the following code:

#include <stdio.h>

int main() {
    char signedChar = 0xf0;

    printf("Signed\n”);
    printf(“Raw: %02X\n”, signedChar);
    printf(“Masked: %02X\n”, signedChar &0xff);
    printf(“Cast: %02X\n", (unsigned char)signedChar);

    return 0;
}

This gives the following output:

Signed
Raw: FFFFFFF0
Masked: F0
Cast: F0

The format string used for each of the prints is %02X, which I’ve always interpreted as ‘print the supplied int as a hexadecimal value with at least two digits’.

The first case passes the signedCharacter as a parameter and prints out the wrong value (because the other three bytes of the int have all of their bits set).

The second case gets around this problem, by applying a bit mask (0xFF) against the value to remove all but the least significant byte, where the char is stored. Should this work? Surely: signedChar == signedChar & 0xFF?

The third case gets around the problem by casting the character to an unsigned char (which seems to clear the top three bytes?).

For each of the three cases above, can anybody tell me if the behavior defined? How/Where?

like image 670
forsvarir Avatar asked May 20 '11 08:05

forsvarir


People also ask

What does %% mean in printf?

Save this answer. Show activity on this post. % indicates a format escape sequence used for formatting the variables passed to printf() . So you have to escape it to print the % character.

What is %d %f %s in C?

The first argument to printf is a string of identifiers. %s refers to a string %d refers to an integer %c refers to a character. Therefore: %s%d%s%c\n prints the string "The first character in sting ", %d prints i, %s prints " is ", and %c prints str[0]. Follow this answer to receive notifications.

How does %s work with printf?

%s and string We can print the string using %s format specifier in printf function. It will print the string from the given starting address to the null '\0' character. String name itself the starting address of the string. So, if we give string name it will print the entire string.

How does %s work in C?

%c deals with a char (that is, a single character), whereas %s deals with a char * (that is, a pointer to an array of characters, hopefully null-terminated).


1 Answers

I don't think this behavior is completely defined by c standard. After all it depends on binary representation of signed values. I will just describe how it's likely to work.

printf(“Raw: %02X\n”, signedChar);

(char)0xf0 which can be written as (char)-16 is converted to (int)-16 its hex representation is 0xfffffff0.

printf(“Masked: %02X\n”, signedChar &0xff);

0xff is of type int so before calculating &, signedChar is converted to (int)-16. ((int)-16) & ((int)0xff) == (int)0x000000f0.

printf(“Cast: %02X\n", (unsigned char)signedChar);

(unsigned char)0xf0 which can be written as (unsigned char)240 is converted to (unsigned int)240 as hex it's 0x000000f0

like image 79
Piotr Praszmo Avatar answered Sep 27 '22 20:09

Piotr Praszmo