0

Okay so I am trying to print hexadecimal values of a struct. Now my print function does the following:

int len = sizeof(someStruct);
unsigned char *buffer = (unsigned char*)&someStruct;
int count;
for(count = 0; count < len; count++) {
    fprintf(stderr, "%02x ", buffer[count]);
}
fprintf(stderr, "\n");

Here is the definition of the struct:

struct someStruct {
   unsigned char a;
   short myShort;
} __attribute__((packed)) someStruct;

The length of this struct printed out as expected is (output on console):

sizeof(someStruct): 3 bytes

Issue here is the following that I am encountering. There is a short which I set to a value.

someStruct.myShort = 0x08;

Now this short is 2 bytes long. When it is printed out into the console however, it does not show the most significant 0x00. Here is the output I get,

stderr: 00 08

I would like the following output however (3 bytes long),

stderr: 00 00 08 

If I fill the short with a 0xFFFF, then I do get the 2 byte output, however, whenever there is leading 0x00, it does not output the leading 0x00 to console.

Any ideas on what I am doing wrong. Probably something small I would assume I am overlooking.

Edwin
  • 797
  • 2
  • 14
  • 23
  • How are you printing the value of `someStruct.myShort`? If you're using the `for` loop you showed us, where are `len` and `buffer` coming from? – Keith Thompson Nov 05 '13 at 19:34
  • 1
    Assuming `buffer = (unsigned char*)&someStruct; len = sizeof(someStruct)` I don't see anything wrong with your code. Could you post a self-contained example demonstrating your problem? – user786653 Nov 05 '13 at 19:34
  • Can you show the definition of `someStruct`, and also print the value of `len`? – Martin R Nov 05 '13 at 19:51
  • Now that OP has changed the question, is there really still a problem? – chux - Reinstate Monica Nov 05 '13 at 19:53
  • Initially the question wasn't clear, I just cleared it up a bit. Sorry about that. But the problem still remains of how to print just the single leading 0x00 bytes of the short – Edwin Nov 05 '13 at 19:58
  • @Edwin Please post a sample of your revised code's output and what you would like it to be. – chux - Reinstate Monica Nov 05 '13 at 19:59
  • 1
    The output (on a little-endian machine) should be `nn 08 00`, where `nn` is the value of the first struct member `a`. If `len = sizeof(someStruct) = 3`, then your code should print three hex bytes. – Martin R Nov 05 '13 at 20:00
  • 1
    Please provide the actual output of the program. If your length (sizeof) is 3, you should see `xx xx xx`, not a single `xx`. –  Nov 05 '13 at 20:02
  • @MartinR, Yup, the length is correct however, the leading 00 does not seem to get printed. It seems to only get printed when the leading bits are not 00. It seems to ignore 00 for some reason on the pring – Edwin Nov 05 '13 at 20:02
  • When I run your code (suitably wrapped in a `main` function), it always prints 3 bytes flawlessly. You have something else going on. Please post a [SSCCE](http://sscce.org/) – Chris Dodd Nov 05 '13 at 20:04
  • Print `len` as part of output, or use a debugger. –  Nov 05 '13 at 20:05
  • 1
    @Edwin: That is very strange, and I cannot reproduce it. Is that your real code? Did you try single-stepping in the debugger? – Martin R Nov 05 '13 at 20:06
  • 1
    I'll have a go with the debugger, something fishy is going on here... – Edwin Nov 05 '13 at 20:07
  • @MartinR, your suggestion on the endianess was very helpeful. There was something fishy with the console session I had open. – Edwin Nov 05 '13 at 20:20

5 Answers5

1

I don't see a problem with your code. However, I get 08 00, which makes sense on my little-endian Intel machine.

Fred Larson
  • 60,987
  • 18
  • 112
  • 174
  • Hi Fred, Note that the struct being printed prints byte by byte. The buffer[count] is a single byte (unsigned char). So although your 04x will work at face value, it is not exactly printing the short. It is just padding the byte with 0's instead of printed the leading 0x00 of the short – Edwin Nov 05 '13 at 19:45
  • 1
    @Edwin: Your code example doesn't make that clear. Please show the declaration and assignment of `buffer`. – Fred Larson Nov 05 '13 at 19:46
  • @Fred Larson If `buffer[count]` is 0xF123, `msb` becomes `fff2` and `fprintf(stderr, "%02x", msb)` prints `fffffff2`. – chux - Reinstate Monica Nov 05 '13 at 19:50
1

After you provided more info, your code is OK for me. It prints the output:

00 08 00

First 00 is from unsigned char a; and second bytes 08 00 are from short. They are switched because of platform dependent data storing in memory.

If you want switched bytes of the short you could just show a short:

fprintf(stderr, "%02x %02x", (someStruct.myShort >> 8) & 0xFF, someStruct.myShort & 0xFF)
Knight of Ni
  • 1,780
  • 3
  • 20
  • 47
  • so to add to this, basically the issue was with the endianess of the system plus configuration error on the shell which was making it skip some prints. – Edwin Nov 06 '13 at 23:29
0

The problem is in the format of the printf

%02x

%02x means that the result will be printed as hex value (x), with a minimum lenght of 2 (2) and filling the spaces with 0 (0)

Try with

fprintf(stderr, "%04x ", buffer[count]); 
Evans
  • 1,589
  • 1
  • 14
  • 25
  • Hi Evan, the thing is however that I am printing it in the function per byte. So that means that printing %04x would just print like this: 0008. But note, that is not the 2 bytes I want, it's just the single byte printed with leading 0's. which is not what is desired here. – Edwin Nov 05 '13 at 19:38
  • 1
    @Edwin: Your question isn't clear. There's not connection between `buffer` and `someStruct.myShort` in your code example, making it difficult to understand what your looking for. – Fred Larson Nov 05 '13 at 19:45
0

The width specifier in the format string (2 in your case) refers to the minimum number of characters in the text output, not the number of bytes to print. Try using "%04x " as your format string instead.

As for the digit grouping (00 08 as opposed to 0008): Plain old printf doesn't support that, but POSIX printf does. Info here: Digit grouping in C's printf

Community
  • 1
  • 1
Imre Kerr
  • 2,388
  • 14
  • 34
0

Need to take care not to shift in a signed bit should buffer be signed. Use "hh" to only print 1 byte worth of data. "hh" available with C99. See What is the purpose of the h and hh modifiers for printf?

fprintf(stderr, "%02hhx %02hhx", buffer[count] >> 8, buffer[count]);

[Edit OP's latest edit wants to see 3 bytes] This will print all field's contents. Each field is in the endian order of the machine.

size_t len = sizeof(someStruct);
const unsigned char *buffer = (unsigned char*)&someStruct;
size_t count;
for(count = 0; count < len; count++) {
    fprintf(stderr, "%02x ", buffer[count]);
}
fprintf(stderr, "\n");
Community
  • 1
  • 1
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256