Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C - Printing negative int values as hex produces too many characters

Tags:

c

Compile using gcc 4.1.2 on CentOS-5 64 bit.

Printing an integer as a two-character hex string:

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

int main(void)
{
   int8_t iNegVar = -1;
   int8_t iPosVar =  1;

   printf(" int negative var is <%02X>\n", iNegVar);
   printf(" int positive var is <%02X>\n", iPosVar);

   return 0;
}

Since the value is only 1 byte, I expect that an integer value of '-1' would print "0xFF". However, I get:

 int negative var is <FFFFFFFF>
 int positive var is <01>

I tried abstracting this to a char* buffer to print 1 byte at a time. This yielded the same results:

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

void print_hex(void* pBuffer, uint8_t uiBufSize);
int main(void)
{
   int8_t iNegVar = -1;
   int8_t iPosVar =  1;

   printf(" int negative var is <%02X>\n", iNegVar);
   print_hex(&iNegVar, 1);                               //pass by reference 


   printf(" int positive var is <%02X>\n", iPosVar);
   print_hex(&iPosVar, 1);                               //pass by reference

   return 0;
}


void print_hex(void* pBuffer, uint8_t uiBufSize)
{
   int i;
   char pTmp[3];                                 //Holds 2-character string, plus NULL
   char* pByteBuff = pBuffer;                    //Use char* to parse byte-by-byte

   for(i = 0; i < uiBufSize; i++)                //Process all bytes in buffer
   {
      sprintf(pTmp, "%02X", pByteBuff[i]);       //store each byte as 2-character string in "pTmp"
      printf(" Converted to %s!\n\n", pTmp);
   }
}

Prints:

int negative var is <FFFFFFFF>
Converted to FFFFFFFF!

int positive var is <01>
Converted to 01!

I got thinking that "char" is implemented in C as an integer type, so I decided to try changing "char* pByteBuff" to "unsigned char* pByteBuff" in the "print_hex" function. This worked, and only printed the two characters I was expecting:

int negative var is <FFFFFFFF>
Converted to FF!

While this "fixed" my issue, the question remains: Why does an explicit printing as a two-character hex value print 8 characters instead of the two that are specified?

like image 998
guidotex Avatar asked May 21 '15 15:05

guidotex


1 Answers

A int8_t will go through the usual integer promotions as a parameter to a variadic function like printf(). This typically means the int8_t is converted to int.

Yet "%X" is meant for unsigned arguments. So covert to some unsigned type first and use a matching format specifier:

For uint8_t, use PRIX8. With exact width types, include <inttypes.h> for the matching specifiers.

#include <inttypes.h>
printf(" int negative var is <%02" PRIX8 ">\n", iNegVar);`

With int8_t iNegVar = -1;, convert to some unsigned type before printing in hex

printf(" int negative var is <%02" PRIX8 ">\n", (uint8_t) iNegVar);`
like image 102
chux - Reinstate Monica Avatar answered Sep 20 '22 15:09

chux - Reinstate Monica