Sandeep
Sandeep

Reputation: 19462

Using snprintf to print restricted hex value

#include <stdio.h>
#include <string.h>

main()
{
    char buff[255];
    snprintf(buff, 255, "%02x", 0xFFFFFF);
    printf("%s\n", buff);
}

I am expecting the above code to print ff(since I gave %02x) but the op is fffff. What am i doing wrong?

Upvotes: 1

Views: 8059

Answers (3)

mafso
mafso

Reputation: 5543

As Unwind’s answer says, you can only pass a minimum, not a maximum field-width to *printf for integer conversions.

As long as you only convert an integer per call, you can use the size argument to snprintf:

snprintf(buff, 3, "%02x", 0x9abcdef);

Output (with the otherwise unchanged code):

9a

I changed the number being converted to illustrate the difference to masking, 0x9abcdef & 0xff is 0xef and masking with 0xff000000 (the highest-order bytes of a 4-byte integer) yields 0x9. I don't know of an easier way to get the two highest-order non-zero nibbles (0-padded on the left if they don’t exist).

Upvotes: 0

David Ranieri
David Ranieri

Reputation: 41026

You can use a binary mask, change:

snprintf(buff, 255, "%02x", 0xFFFFFF);

to

snprintf(buff, 255, "%02x", 0xFFFFFF & 0x0000FF);

E.g.:

#include <stdio.h>

int main(void) /* main() is not valid */
{
    char buff[255];
    snprintf(buff, 255, "%02x", 0x00BEEF & 0x0000FF);
    printf("%s\n", buff);
    return 0;
}

Output:

ef

Upvotes: 3

unwind
unwind

Reputation: 399959

Your expectations are wrong.

From the manual page for the *printf() family:

In no case does a nonexistent or small field width cause truncation of a field; if the result of a conversion is wider than the field width, the field is expanded to contain the conversion result.

You can truncate strings using the precision (".N") modifier, but not using field width:

printf("%2s and %.2s", "foo", "foo");

prints

foo and fo

You can't use precision to truncate integers.

Upvotes: 4

Related Questions