Reputation: 95
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
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
Reputation: 409216
The problem is a combination of two things:
printf
it's converted to an int
, which might include sign extension."%x"
you are using expects the corresponding argument to be an unsigned int
and treat it as suchIf 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
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