C: Add auto prefix to hex calculation

-1

This is my C program

#include <stdio.h>
void main() {
    printf("Diff = %x\n",0xffffffff-0xfffffffa);
}

And the standard output would be like this

C:\Codes>prog.exe
Diff = 5

What I'm trying to achieve is to add auto prefix 0x00000005 automatically to the answer so the output would be like this.

C:\Codes>prog.exe
Diff = 0x00000005

or

C:\Codes>prog.exe
Diff = 0x00000A35

I know we can do this manually with this code

#include <stdio.h>
void main() {
    printf("Diff = 0x0000000%x\n",0xffffffff-0xfffffffa);
}

But, is it possible to accomplish this without manually write 0x0000000%x in printf?

c
asked on Stack Overflow Jul 4, 2017 by Charlotte Russell • edited Jul 4, 2017 by Charlotte Russell

2 Answers

3

Yes it's possible:

printf("0x%08x\n", 0xffffffff-0xfffffffa);

Most good beginners books would have some text about formatting options. And there's always good references to read.

2

Hexadecimal prefix

There are multiple ways to add the hexadecimal prefix to the output:

#include <stdio.h>

int main(void)
{
    printf("Diff = %#x\n",  0xFFFFFFFF - 0xFF012345);
    printf("Diff = %#X\n",  0xFFFFFFFF - 0xFF012345);
    printf("Diff = 0x%X\n", 0xFFFFFFFF - 0xFF012345);

    printf("Diff = %#.8x\n",  0xFFFFFFFF - 0xFF012345);
    printf("Diff = %#.8X\n",  0xFFFFFFFF - 0xFF012345);
    printf("Diff = 0x%.8X\n", 0xFFFFFFFF - 0xFF012345);
    return 0;
}

The output is:

Diff = 0xfedcba
Diff = 0XFEDCBA
Diff = 0xFEDCBA
Diff = 0x00fedcba
Diff = 0X00FEDCBA
Diff = 0x00FEDCBA

You can choose the 0x lower-case prefix with the lower-case hex digits, or the upper-case prefix with the upper-case digits. Personally, I like the lower-case prefix and the upper-case digits, so I always use the third option.

The # flag for printf() chooses an alternative representation:

# —  Specifies that the value is to be converted to an alternative form. For o conversion, it shall increase the precision, if and only if necessary, to force the first digit of the result to be a zero (if the value and precision are both 0, a single 0 is printed). For x or X conversion specifiers, a non-zero result shall have 0x (or 0X) prefixed to it. For a, A, e, E, f, F, g, and G conversion specifiers, the result shall always contain a radix character, even if no digits follow the radix character. Without this flag, a radix character appears in the result of these conversions only if a digit follows it. For g and G conversion specifiers, trailing zeros shall not be removed from the result as they normally are. For other conversion specifiers, the behavior is undefined.

Leading zeros

You can specify the number of digits in various ways, not always with the desired result when using the manual prefix. Note that the prefix is counted in the minimum field width when the # flag is used.

#include <stdio.h>

int main(void)
{
    printf("Diff = %#x\n",  0xFFFFFFFF - 0xFF012345);
    printf("Diff = %#X\n",  0xFFFFFFFF - 0xFF012345);
    printf("Diff = 0x%X\n", 0xFFFFFFFF - 0xFF012345);

    printf("Diff = %#.8x\n",  0xFFFFFFFF - 0xFF012345);
    printf("Diff = %#.8X\n",  0xFFFFFFFF - 0xFF012345);
    printf("Diff = 0x%.8X\n", 0xFFFFFFFF - 0xFF012345);

    printf("Diff = %#10x\n",  0xFFFFFFFF - 0xFF012345);
    printf("Diff = %#10X\n",  0xFFFFFFFF - 0xFF012345);
    printf("Diff = 0x%10X\n", 0xFFFFFFFF - 0xFF012345);

    printf("Diff = %#10.10x\n",  0xFFFFFFFF - 0xFF012345);
    printf("Diff = %#10.10X\n",  0xFFFFFFFF - 0xFF012345);
    printf("Diff = 0x%10.10X\n", 0xFFFFFFFF - 0xFF012345);
    return 0;
}

Output:

Diff = 0xfedcba
Diff = 0XFEDCBA
Diff = 0xFEDCBA
Diff = 0x00fedcba
Diff = 0X00FEDCBA
Diff = 0x00FEDCBA
Diff =   0xfedcba
Diff =   0XFEDCBA
Diff = 0x    FEDCBA
Diff = 0x0000fedcba
Diff = 0X0000FEDCBA
Diff = 0x0000FEDCBA

On 32-bit systems, I normally use 0x%8.8X; on 64-bit systems, I use one of 0x%12.12X or 0x%16.16X. The latter often leaves the addresses I'm printing with more leading zeros than I want.

You can left-justify if you need to, and so on and so forth. See the specification of printf() already linked, which is formally for POSIX but the POSIX extensions are clearly marked.

And for printing addresses, I use uintptr_t and PRIXPTR from <inttypes.h>, leading to a format string along the lines of:

printf("0x%8.8" PRIXPTR "\n", (uintptr_t)&x);

As you can see, there are many variations that can be used — you need to choose what works best for you.

answered on Stack Overflow Jul 4, 2017 by Jonathan Leffler • edited Jul 4, 2017 by Jonathan Leffler

User contributions licensed under CC BY-SA 3.0