views:

241

answers:

2

I want these two print functions to do the same thing:

    unsigned int Arraye[] = {0xffff,0xefef,65,66,67,68,69,0};
            char Arrage[] = {0xffff,0xefef,65,66,67,68,69,0};
    printf("%s", (char*)(2+ Arraye));
    printf("%s", (char*)(2+ Arrage));

where Array is an unsigned int. Normally, I would change the type but, the problem is that most of the array is numbers, although the particular section should be printed as ASCII. Currently, the unsigned array prints as "A" and the char array prints as the desired "ABCDE".

+1  A: 

This is how the unsigned int version will be arranged in memory, assuming 32-bit big endian integers.

00 00 ff ff 00 00 ef ef 00 00 00 41 00 00 00 42
00 00 00 43 00 00 00 44 00 00 00 45 00 00 00 00

This is how the char version will be arranged in memory, assuming 8-bit characters. Note that 0xffff does not fit in a char.

ff ef 41 42 43 44 45 00

So you can see, casting is not enough. You'll need to actually convert the data.

If you know that your system uses 32-bit wchar_t, you can use the l length modifier for printf.

printf("%ls", 2 + Arraye);

This is NOT portable. The alternative is to copy the unsigned int array into a char array by hand, something like this:

void print_istr(unsigned int const *s)
{
    unsigned int const *p;
    char *s2, *p2;
    for (p = s; *p; p++);
    s2 = xmalloc(p - s + 1);
    for (p = s, p2 = s2; *p2 = *p; p2++, p++);
    fputs(s2, stdout);
    free(s2);
}
Dietrich Epp
Thanks for the clarification, I ended up doing something like this.
Misha
I suggested another solution because I do not like functions that allocate memory for temporaries.
tristopia
A: 

As Dietrich said, a simple cast will not do, but you don't need a complicated conversion either. Simply loop over your array.

uint_t Arraye[] = {0xffff,0xefef,65,66,67,68,69,0};
  char Arrage[] = {0xffff,0xefef,65,66,67,68,69,0};

uint_t *p;
for(p = Arraye+2; p; p++)
  printf("%c", p);

printf("%s", (char*)(2+ Arrage));
tristopia