[ACCEPTED]-How to convert struct to char array in C-char

Accepted answer
Score: 11

What you see is the sign preserving conversion 14 from char to int. The behavior results from 13 the fact that on your system, char is signed 12 (Note: char is not signed on all systems). That 11 will lead to negative values if a bit-pattern 10 yields to a negative value for a char. Promoting 9 such a char to an int will preserve the 8 sign and the int will be negative too. Note 7 that even if you don't put a (int) explicitly, the 6 compiler will automatically promote the 5 character to an int when passing to printf. The 4 solution is to convert your value to unsigned char first:

for (i=0; i<4; i++)
   printf("%02x ", (unsigned char)b[i]);

Alternatively, you 3 can use unsigned char* from the start on:

unsigned char *b = (unsigned char *)&a;

And then you 2 don't need any cast at the time you print 1 it with printf.

Score: 8

char is a signed type; so with two's complement, 0x80 1 is -128 for an 8-bit integer (i.e. a byte)

Score: 8

The x format specifier by itself says that 14 the argument is an int, and since the number 13 is negative, printf requires eight characters 12 to show all four non-zero bytes of the int-sized 11 value. The 0 modifier tells to pad the output 10 with zeros, and the 2 modifier says that 9 the minimum output should be two characters long. As 8 far as I can tell, printf doesn't provide a way 7 to specify a maximum width, except for strings.

Now 6 then, you're only passing a char, so bare x tells 5 the function to use the full int that got passed 4 instead — due to default argument promotion 3 for "..." parameters. Try the hh modifier to 2 tell the function to treat the argument 1 as just a char instead:

printf("%02hhx", b[i]);
Score: 5

Treating your struct as if it were a char 6 array is undefined behavior. To send it 5 over the network, use proper serialization 4 instead. It's a pain in C++ and even more 3 so in C, but it's the only way your app 2 will work independently of the machines 1 reading and writing.


Score: 2

Converting your structure to characters 7 or bytes the way you're doing it, is going 6 to lead to issues when you do try to make 5 it network neutral. Why not address that 4 problem now? There are a variety of different 3 techniques you can use, all of which are 2 likely to be more "portable" than 1 what you're trying to do. For instance:

  • Sending numeric data across the network in a machine-neutral fashion has long been dealt with, in the POSIX/Unix world, via the functions htonl, htons, ntohl and ntohs. See, for example, the byteorder(3) manual page on a FreeBSD or Linux system.
  • Converting data to and from a completely neutral representation like JSON is also perfectly acceptable. The amount of time your programs spend converting the data between JSON and native forms is likely to pale in comparison to the network transmission latencies.
Score: 1

char is a signed type so what you are seeing 4 is the two-compliment representation, casting 3 to (unsigned char*) will fix that (Rowland 2 just beat me).

On a side note you may want 1 to change

for (i=0; i<4; i++) {


for (i=0; i<sizeof(x); i++) {
Score: 1

The signedness of char array is not the 18 root of the problem! (It is -a- problem, but 17 not the only problem.)

Alignment! That's 16 the key word here. That's why you should 15 NEVER try to treat structs like raw memory. Compliers 14 (and various optimization flags), operating 13 systems, and phases of the moon all do strange 12 and exciting things to the actual location 11 in memory of "adjacent" fields in a structure. For 10 example, if you have a struct with a char 9 followed by an int, the whole struct will 8 be EIGHT bytes in memory -- the char, 3 7 blank, useless bytes, and then 4 bytes for 6 the int. The machine likes to do things 5 like this so structs can fit cleanly on 4 pages of memory, and such like.

Take an introductory 3 course to machine architecture at your local 2 college. Meanwhile, serialize properly. Never 1 treat structs like char arrays.

Score: 1

When you go to send it, just use:


to 1 convert. Works for me.

Score: 0

You may want to convert to a unsigned char 1 array.

More Related questions