Monika
Monika

Reputation:

Can someone explain unexpected sprintf output?

I have a very simple sprintf question.

int STATUS = 0;

char test[100];
int n = sprintf( test,"%04x", STATUS );
printf ("[%s] is a %d char long string\n",test,n);  

for(i=0 ; i<4 ; i++) {
  printf("%02x", test[i]); 
    }   
    printf("\n\n"); 

The output of this code is 30303030 which is not what I intend to have as output. Basically, I would like to have 00000000 as output, so integer value should occupy 4 bytes in my output with its actual value. Can anybody tell me what I did wrong?

Upvotes: 1

Views: 617

Answers (6)

tschaible
tschaible

Reputation: 7695

printf expects to get a number as an argument when printing anything with specifier x. You are passing in a character so it's printing out the ascii value of the character. Try changing

printf("%02x", test[i]); 

to

printf("%02x", test[i] - 0x30); 

Upvotes: 0

caf
caf

Reputation: 239041

If what you're asking is to be certain that your STATUS variable is 4 bytes wide, then include inttypes.h (a C99 header) and declare it as:

uint32_t STATUS = 0;

if you also want to be certain it is big-endian, you will have to declare it as an array of bytes:

unsigned char STATUS[4] = { 0x00, 0x00, 0x00, 0x01 } /* STATUS = 1, 32bit BE */

Pretty sure that's the best you can do in portable C.

Upvotes: 0

anon
anon

Reputation:

The call:

 printf("%02x", test[i]);

is printing each character as an integer using 2 hex digits. 30 is hex for 48, which is the ascii value for '0'. Change to

 printf("%02c", test[i]); 

although I;m not sure this will dom what you want in the general case.

Upvotes: 1

Jon Hess
Jon Hess

Reputation: 14247

It's printing 30 instead of 00 because you're printing the integer value of the character '0', which in ASCII is 0x30, or 48 in decimal.

If you'd like to see the raw bytes that are used to define an integer, you might try something like this.

typedef union {
    int integerValue;
    uint8_t bytes[sizeof(int)];
} MyIntegerOrBytes;

void foo(void) {
    MyIntegerOrBytes value;
    value.integerValue = 100;
    for(int i = 0; i < sizeof(int); i += 1) {
        printf("byte[%d] = %d\n", i, value.bytes[i]);
    }
}

Upvotes: 0

Henk Holterman
Henk Holterman

Reputation: 273229

0x30 is the ASCII code for '0', you are mixing char and int representations.

Upvotes: 4

Josip Medved
Josip Medved

Reputation: 3711

It seems that you are converting this to hex. 30 is hex for character '0'. Modify first sprintf to:

int n = sprintf( test,"%4d", STATUS );

or just have

printf("%08x", STATUS);

Upvotes: 2

Related Questions