【问题标题】:printing the hex values after storing it to an array using C使用 C 将十六进制值存储到数组后打印
【发布时间】:2016-03-09 01:18:15
【问题描述】:

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

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]);
}

【问题讨论】:

  • 我看到两个潜在的(但不相关的)问题:首先是 C 中的 don't cast the return of malloc (and friends)(或任何返回 void * 的函数)。其次,变量 c 和 int 还是 char?请记住 fgetc 返回一个 int。还有很多变量你在任何地方都没有真正使用,比如ic,你从来没有真正用它做任何事情吗?
  • 那么您的代码将无法按预期工作,因为(char) EOF != (int) EOF
  • 非常感谢您抽出宝贵的时间。现在已经解决了。问题在于错误的数据类型声明

标签: c arrays hex


【解决方案1】:

问题是两件事的结合:

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

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

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

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

【讨论】:

  • 使用hh 不够便携。尽管它是自 C99 以来的标准,但 Microsoft 不支持它(根据今天的 MSDN 版本)。
  • @Netch 仅部分正确,VS2015 includes a fully conformant C99 standard library(取决于缺少的编译器功能的功能除外,printf 格式化字符串不应该是这样的依赖功能)。我不知道是真的实现了还是MSDN页面没有正确更新。
【解决方案2】:

默认情况下,char 已在许多平台上签名(标准并未规定其签名)。传递给变量参数列表时,会调用像 char -> int 这样的标准扩展。如果 char 是无符号的,0xd3 仍然是整数 0xd3。如果 char 有符号,则 0xd3 变为 0xffffffd3(对于 32 位整数),因为这是相同的整数值 -45

注意,如果您没有意识到这一点,您应该重新检查整个程序,因为此类错误非常微妙。我曾经处理过一个工具,该工具仅适用于强制 -funsigned-char 到 make 的 CFLAGS。 OTOH,如果您可以使用此标志,则可能是解决此问题的快速而肮脏的解决方案(但我建议您避免使用它,以备更长时间使用)。

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2011-01-20
      • 1970-01-01
      • 2013-11-21
      • 2015-02-14
      • 1970-01-01
      • 1970-01-01
      • 2014-09-18
      • 1970-01-01
      • 2012-10-07
      相关资源
      最近更新 更多