Skip to content
Advertisement

How do I print array of u16 in C?

I’d like to print both MSB and LSB of a u16 variable, here is my code:

__u16 reg = 0x10A0; /* Device register to access */
__s32 res;
char buf[10];

buf[0] = reg;

printf("0x%Xn", buf[0]);

This code just print the LSB part in hexa format, but can you tell me how do I print the MSB part?

Advertisement

Answer

This code just print the LSB part

Well of course, buf[0] = reg; only copies 8 bits.

And what result you get isn’t well-defined, because char cannot reliably store raw binary. It might be signed on your systems and then you can get all kinds of subtle bugs because of it.

Step 1 is to fix your types. Get rid of char as well as the home-made, garage standard integer types, in favour for standard C types:

#include <stdint.h>

uint16_t reg = 0x10A0u; 
uint8_t  buf [10];

Then decide the byte order of your array. Assuming that you want index 0 to be the most significant byte, then the quick & dirty version looks like this:

buf[0] = reg >> 8;
buf[1] = reg;

This will work in this specific case. However, good compilers will moan about implicit promotions and similar. Strictly speaking, you should make a habit of always casting to uint32_t before doing any kind of shifting (assuming >=32 bit system). We can make the code more rugged and silence warnings like this:

buf[0] = ((uint32_t)reg >> 8) & 0xFFu;
buf[1] = ((uint32_t)reg >> 0) & 0xFFu;

This method safely scales to larger types as well.

Also, be vary of various quack solutions on SO and elsewhere telling you to use union or character pointers for this. Such solutions make the code needlessly endianess dependent for nothing gained. The shift version is 100% portable even across different endianess CPUs.

Then finally, printing with printf. You can get the correct format specifier for any uintn_t automatically from the header inttypes.h. It provides PRIx8 for lower case hex and PRIX8 for upper case hex.

Complete program:

#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>

int main (void)
{
  uint16_t reg = 0x10A0u; 
  uint8_t  buf[10];

  buf[0] = ((uint32_t)reg >> 8) & 0xFFu;
  buf[1] = ((uint32_t)reg >> 0) & 0xFFu;

  printf("0x%"PRIX8 "%"PRIX8 "n", buf[0], buf[1]);
}
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement