Parvathi
Parvathi

Reputation: 95

printing the hex values after storing it to an array using C

I have done the reading from a file and is stored as hex values(say the first value be D4 C3). This is then stored to a buffer of char datatype. But whenever i print the buffer i am getting a value likebuff[0]=ffffffD4; buff[1]=ffffffC3 and so on. How can I store the actual value to the buffer without any added bytes? Attaching the snippet along with this

ic= (char *)malloc(1);
temp = ic;  
int i=0;
char buff[1000];

while ((c = fgetc(pFile)) != EOF) 
{
  printf("%x",c);
  ic++;        
  buff[i]=c;
  i++;
}
printf("\n\nNo. of bytes written: %d", i);
ic = temp;
int k;
printf("\nBuffer value is :   ");
for(k=0;k<i;k++)
{
  printf("%x",buff[k]);
}

Upvotes: 3

Views: 786

Answers (3)

Netch
Netch

Reputation: 4572

By default, char is signed on many platforms (standards doesn't dictate its signedness). When passing to variable argument list, standard expansions like char -> int are invoked. If char is unsigned, 0xd3 remains integer 0xd3. If char is signed, 0xd3 becomes 0xffffffd3 (for 32-bit integer) because this is the same integer value -45.

NB if you weren't aware of this, you should recheck the entire program, because such errors are very subtle. I've dealed once with a tool which properly worked only with forced -funsigned-char into make's CFLAGS. OTOH this flag, if available to you, could be a quick-and-dirty solution to this issue (but I suggest avoiding it for any longer appoaching).

The approach I'm constantly using is passing to printf()-like functions a value not c, but 0xff & c, it's visually easy to understand and stable for multiple versions. You can consider using hh modifier (UPD: as @JoachimPileborg have already suggested) but I'm unsure it's supported in all real C flavors, including MS and embedded ones. (MSDN doesn't list it at all.)

Upvotes: 1

Some programmer dude
Some programmer dude

Reputation: 409216

The problem is a combination of two things:

  • First is that when you pass a smaller type to a variable argument function like printf it's converted to an int, which might include sign extension.
  • The second is that the format "%x" you are using expects the corresponding argument to be an unsigned int and treat it as such

If you want to print a hexadecimal character, then use the prefix hh, as in "%hhx".

See e.g. this printf (and family) reference for more information.

Finally, if you only want to treat the data you read as binary data, then you should consider using int8_t (or possibly uint8_t) for the buffer. On any platform with 8-bit char they are the same, but gives more information to the reader of the code (saying "this is binary data and not a string").

Upvotes: 5

David Schwartz
David Schwartz

Reputation: 182789

You did store the actual values in the buffer without the added bytes. You're just outputting the signed numbers with more digits. It's like you have "-1" in your buffer but you're outputting it as "-01". The value is the same, it's just you're choosing to sign extend it in the output code.

Upvotes: 1

Related Questions