使用C

时间:2015-12-04 07:05:45

标签: c arrays hex

我已经从文件中读取并存储为十六进制值(比如第一个值为D4 C3)。然后将其存储到char数据类型的缓冲区中。但每当我打印缓冲区时,我得到的值都是buff[0]=ffffffD4; buff[1]=ffffffC3等等。 如何在不添加任何字节的情况下将实际值存储到缓冲区? 将代码段与此

一起附加
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]);
}

3 个答案:

答案 0 :(得分:5)

问题是两件事的结合:

  • 首先,当您将较小的类型传递给printf等变量参数函数时,它会转换为int,其中可能包含符号扩展名。
  • 第二个是你正在使用的格式"%x"期望的相应参数 unsigned int并将其视为

如果要打印十六进制字符,请使用前缀hh,如"%hhx"中所示。

参见例如this printf (and family) reference了解更多信息。

最后,如果您只想将读取的数据视为二进制数据,则应考虑使用int8_t(或可能uint8_t)作为缓冲区。在任何具有8位char的平台上它们是相同的,但是向代码的读者提供了更多信息(说&#34;这是二进制数据而不是字符串&#34;)。

答案 1 :(得分:1)

您确实将实际值存储在缓冲区中而没有添加字节。您只是输出带有更多数字的带符号数字。这就像你的缓冲区中有“-1”但你输出它为“-01”。值是相同的,只是你选择在输出代码中签名扩展它。

答案 2 :(得分:1)

默认情况下,char在许多平台上签名(标准并未规定其签名)。传递给可变参数列表时,标准扩展如char - &gt;调用int。如果char是无符号的,则0xd3保持为整数0xd3。如果char被签名,则0xd3变为0xffffffd3(对于32位整数),因为这是相同的整数值-45

注意,如果您没有意识到这一点,您应该重新检查整个程序,因为这些错误非常微妙。我已经使用只有强制-funsigned-char才能正常使用的工具进行了一次处理CFLAGS。 OTOH这个标志,如果可以的话,对于这个问题可能是一个快速而肮脏的解决方案(但我建议不再使用它)。

我经常使用的方法是传递给printf() - 类似函数的值不是c,而是0xff & c,它在视觉上易于理解并且对于多个来说是稳定的版本。您可以考虑使用hh修饰符(UPD:正如@JoachimPileborg已经建议的那样),但我不确定它是否支持所有真正的C版本,包括MS和嵌入式版本。 (MSDN根本没有列出它。)