Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Reading Hex from file, printf %x showing leading ff values

I have a file ‘data.dat’ with 26 hex byte values:

22 49 E1 09 62 18 42 8C 66 10 B0 11 84 9C 00 FF E0 40 1F F8 60 07 FE 2C 03 FF

I am trying to read these into c++ and print the hex values to the terminal with:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const int msgbuflen = 26;                
char message [msgbuflen];  

const char* filenameIn = "data.dat";  

FILE* fpIn = fopen(filenameIn, "rb");

if (!fpIn) {
  perror("ERROR: INPUT FILE CANNOT BE OPENED\n");
  exit(EXIT_FAILURE);
}

for (i=0; i<msgbuflen; i++){  // clear the buffer
    message[i] = '0';
}

size_t ret_code = fread(message, sizeof(unsigned char), msgbuflen, fpIn);
for(int i = 0; i < msgbuflen; i++){
  printf("message[%d] : 0x%x\n", i, message[i]);
}

fclose (fpIn);

When run the output for some of the bytes have 3 leading ff values:

message[0] : 0x22
message[1] : 0x49
message[2] : 0xffffffe1
message[3] : 0x9
message[4] : 0x62
message[5] : 0x18
message[6] : 0x42
message[7] : 0xffffff8c
message[8] : 0x66
message[9] : 0x10
message[10] : 0xffffffb0
message[11] : 0x11
message[12] : 0xffffff84
message[13] : 0xffffff9c
message[14] : 0x0
message[15] : 0xffffffff
message[16] : 0xffffffe0
message[17] : 0x40
message[18] : 0x1f
message[19] : 0xfffffff8
message[20] : 0x60
message[21] : 0x7
message[22] : 0xfffffffe
message[23] : 0x2c
message[24] : 0x3
message[25] : 0xffffffff

Why do these leading f’s occur? for example message[2] : 0xffffffe1

I have tried formatting the output of the printf hex %x with 0x%01x but it makes no difference to the terminal output. Checking the sizeof each element in the char array, they are still 1 byte as expected:

printf("sizeof(message[2]) : %ld\n", sizeof(message[2]) );

%> sizeof(message[2]) : 1

I am now wondering if this is a formatting problem? There does not appear to be any more than 1 byte in each message element (as expected).

Using std::hex with cout produces the same issue.

>Solution :

This is because char is a signed integer so 0xFF becomes -1. As %x prints an int, which is 32-bits, it becomes 0xFFFFFFFF which is a 32-bit negative one.

If you store as an unsigned char you will not have this problem

#include <cstdio>
int main() {
    unsigned char message[] = {0x22, 0x49, 0xE1, 0x09, 0x62, 0x18, 0x42, 0x8C, 0x66, 0x10, 0xB0, 0x11, 0x84, 0x9C, 0x00, 0xFF, 0xE0, 0x40, 0x1F, 0xF8, 0x60, 0x07, 0xFE, 0x2C, 0x03, 0xFF }; 
    int msgbuflen = sizeof(message)/sizeof(message[0]);
    for(int i = 0; i < msgbuflen; i++){
        printf("message[%d] : 0x%x\n", i, message[i]);
    }
}

Produces

Program returned: 0
message[0] : 0x22
message[1] : 0x49
message[2] : 0xe1
message[3] : 0x9
message[4] : 0x62
message[5] : 0x18
message[6] : 0x42
message[7] : 0x8c
message[8] : 0x66
message[9] : 0x10
message[10] : 0xb0
message[11] : 0x11
message[12] : 0x84
message[13] : 0x9c
message[14] : 0x0
message[15] : 0xff
message[16] : 0xe0
message[17] : 0x40
message[18] : 0x1f
message[19] : 0xf8
message[20] : 0x60
message[21] : 0x7
message[22] : 0xfe
message[23] : 0x2c
message[24] : 0x3
message[25] : 0xff

Godbolt: https://godbolt.org/z/oxPqnYqMq

Alternatively you can just cast

    for(int i = 0; i < msgbuflen; i++){
        printf("message[%d] : 0x%x\n", i, (unsigned char)message[i]);
    }
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading