如何在C语言中将无符号字符数组转换为十六进制字符串

7

能否将无符号字符数组表示为字符串?

当我搜索时,发现只有memset()能够做到这一点(但是需要逐个字符处理)。假设这不是正确的方法,那么有没有其他方法进行转换?

上下文:我正在尝试存储加密哈希函数的输出,它恰好是一个无符号字符数组。
例如:

unsigned char data[N]; ...
for(i=0;i<N;i++) printf("%x",data[i]);

我的目标是将数据表示为字符串(%s),而不是通过每个元素访问它。由于我需要进一步处理哈希的输出结果为字符串。

谢谢!


你实际上想要实现什么?表面上将数组转换为(char*)可以实现你所要求的。 - forsvarir
一个无符号字符数组不就是一个字符串吗?我的意思是,我不知道有任何负的ASCII值... - das_weezul
顺便提一下,memset将缓冲区设置为提供的值,给定次数,所以我真的看不出它会对你有多大帮助... 代码/伪代码示例可能会有所帮助。 - forsvarir
我已经编辑了问题并提供了背景。如果我还不够清楚,请随时指出。 - Maverickgugu
5个回答

22

根据您的更新,您是在尝试将一个无符号字符缓冲区转换为十六进制解释,类似于这样:

#define bufferSize 10
int main() {
  unsigned char buffer[bufferSize]={1,2,3,4,5,6,7,8,9,10};
  char converted[bufferSize*2 + 1];
  int i;

  for(i=0;i<bufferSize;i++) {
    sprintf(&converted[i*2], "%02X", buffer[i]);

    /* equivalent using snprintf, notice len field keeps reducing
       with each pass, to prevent overruns

    snprintf(&converted[i*2], sizeof(converted)-(i*2),"%02X", buffer[i]);
    */

  }
  printf("%s\n", converted);

  return 0;
}

输出结果为:

0102030405060708090A

2
@Maverickgugu:这是可以的...但也很危险 :) 要注意缓冲区溢出,因为它不会进行任何长度检查。有一个更安全的版本(snprintf),它允许您指定可以写入缓冲区的最大大小,您可能需要查看一下。 - forsvarir
@forsvarir:同样的意思..我们能否用字符串的二进制表示来表示无符号字符数组?有建议吗? - Maverickgugu
@Maverickgugu:所以,你想要的不是将它转换为“0A0B”等字符串,而是“000010”,“000011”等吗? - forsvarir
@forsvarir:是的...确切地说...不一定是字符串。即使是一个由0和1组成的整数数组也可以...这可行吗?我已经没有更多的想法了。 - Maverickgugu
1
@Maverickgugu:你没有在这里问过这个问题并得到答案吗:http://stackoverflow.com/questions/5680367/wierd-error-abort-trap-while-handling-character-array-in-c - forsvarir

2
在C语言中,字符串是由以值为0的字符终止的char数组。语言并未规定char类型是有符号还是无符号的,如果你真的关心的话,需要明确使用unsigned charsigned char
如果你说“将无符号字符数组表示为字符串”,那么这个意思不是很清楚。如果你想要做类似以下的操作,强制转换去掉符号是很容易的:
const unsigned char abc[] = { 65, 66,67, 0 }; // ASCII values for 'A', 'B', 'C'.

printf("The English alphabet starts out with '%s'\n", (const char *) abc);

这将有效,在printf()中并没有太大差异,它将看到一个指向字符数组的指针,并将其解释为字符串。

当然,如果您在一个不使用ASCII编码的系统上,则可能会出现无法正常工作的情况。再次强调,您的问题表述不够清晰。


我正在使用MAC工作,如果其中一个无符号字符具有超级值而不是常规ASCII值,类型转换是否仍会产生垃圾值? - Maverickgugu

2

C语言中的字符串就是几个字符一个接一个地排列。它们是无符号或有符号并不是什么大问题,你可以轻松地进行类型转换。

因此,要从无符号字符数组中获取一个字符串,你只需要确保最后一个字节是终止字节'\0',然后将该数组强制转换为char *(或将其复制到char数组中)即可。


谢谢。解决方案看起来很简单。但是我应该将无符号字符数组与字符串连接吗?我是否应该在最后一个元素插入空字符? - Maverickgugu
1
在密码学环境中,这可能并不容易,这取决于您如何处理字符串。您必须记住,哈希函数的输出可能已经包含'\0'字节,而且如果这样的字节出现,您可能最终只能处理字符串的一部分,因为字符串处理函数会停止工作。 - Chris
是的,我完全同意你的推理! - Maverickgugu

1
我成功地使用这个方法将无符号字符数组转换为std:string。
unsigned char array[128];
std::stringstream buffer;
for (int i = 0; i < 128; i++)
    {
        buffer << std::hex << std::setfill('0');
        buffer << std::setw(2)  << static_cast<unsigned>(array[i]);
    }
std::string hexString = buffer.str();

-1

正如您所要求的示例:

无符号字符 arr [SIZE];


那只是声明。我想知道是否可以将这个数组打印为“%s”? - Maverickgugu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接