tags:

views:

185

answers:

6

Hi

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?

Thanks

+2  A: 

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);
Josip Medved
+4  A: 

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

Henk Holterman
Okay that makes sense; however for me it is important that the 0 integer accupies 4 bytes and intialises them to 0x00000000 when STATUS = 0, 0x00000001 when STATUS=1, 0x00000010 when STATUS=2, etc. Am I doing this now with my code and is this just a problem with printf?
An int already occupies 4 bytes (most platforms). You can convert when printing: printf("%02x", test[i] - '0');
Henk Holterman
+1  A: 

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.

anon
A: 

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]-30);
tschaible
Not \-30\ , use \- 0x30\ or \- '0'\
Henk Holterman
A: 

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]);
    }
}
Jon Hess
A: 

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.

caf