如何在C++中将unsigned char*转换为std::string?

50

我有一个 unsigned char*,想要将其转换为 std::string。请问您能告诉我最安全的方法是什么吗?


3
C++中没有字节类型,因此您需要告诉我们实际上是什么类型。 - Yacoby
2
BYTE 解析为 "unsigned char"。 - Unicorn
4
那么Byte类型呢?更重要的是,你的指针指向什么?是一个单独的Byte值还是一个Byte数组?在你的字符串中,你想要表示指针的值的文本表示形式,还是表示所指向的对象/对象们的值的字符串? - CB Bailey
6个回答

76

你只需要将 unsigned char 强制转换为 char,因为 string 类没有接受 unsigned char 的构造函数:

unsigned char* uc;
std::string s( reinterpret_cast< char const* >(uc) ) ;

如果您的字节数组包含空值(nulls),则需要在构造函数中使用length参数,否则只有数组中第一个空值前面的部分会出现在字符串中。

size_t len;
unsigned char* uc;
std::string s( reinterpret_cast<char const*>(uc), len ) ;

BYTE * pbData = "SomeString" size_t length = 10 我提前知道了长度,所以我使用了这个方法: 我使用了这个方法,“std::string(reinterpret_cast<char *>(pbData), length );”它可以工作,但有时候会出现memcpy崩溃的情况。 我正在尝试找出为什么会崩溃,虽然对我来说似乎是有效的。 - Unicorn
7
作为一个追求可移植性的人,我想指出这只适用于使用二进制补码算术的系统。在使用一进制或符号-数值结构的架构上,重新解释 char*unsigned char* 之间的转换是不安全的(嗯,它是安全的,但如果 char 是有符号的且任何字符的最高位设置了,你将会得到令人惊讶的结果)。在这种情况下,提问者显然在使用Windows,所以没有问题。 - Steve Jessop

9

BYTE* 可能是 unsigned char* 的一个 typedef,但我不能确定。如果你告诉我们 BYTE 是什么,会更有帮助。

如果 BYTE*unsigned char*,你可以使用 std::string 范围构造函数将其转换为 std::string,该构造函数将接受两个通用迭代器。

const BYTE* str1 = reinterpret_cast<const BYTE*> ("Hello World");
int len = strlen(reinterpret_cast<const char*>(str1));
std::string str2(str1, str1 + len);

话虽如此,您确定这是个好主意吗?如果BYTEunsigned char,它可能包含非ASCII字符,包括NULL。这将导致strlen给出不正确的长度。


5
BYTE *str1 = "Hello World";
std::string str2((char *)str1);  /* construct on the stack */

或者:

std::string *str3 = new std::string((char *)str1); /* construct on the heap */
cout << &str3;
delete str3;

它不起作用,我收到一个错误消息,说“'std::basic_string<_Elem,_Traits,_Ax>::basic_string(const std::allocator<_Ty> &)':无法将参数1从'BYTE *'转换为'const std::allocator<_Ty> &'”。 - Unicorn
1
这是因为std::string没有一个以unsigned char*为参数的构造函数,所以编译器会退而求其次使用为分配器设计的模板化构造函数。你需要使用std::string(Iterator begin, Iterator end)或者std::string(const char*, std::size_t n),并将BYTE强制转换为char - Charles Salvia
4
“std::string &str3 = new ...”,你是不是指的是 * 而不是 &?顺便说一下,在堆上创建 std::string 通常是一个坏主意,这样做违背了具有值语义的字符串类的一半作用。 - sbk
你没错。我没有像应该做的那样通过编译器运行它。你需要(char *)类型转换,因为std::string不能处理BYTE/unsigned char类型。而且参考示例是错误的;它应该是一个指针。 - spoulson
这个答案有很多问题:C风格的转换,没有必要使用堆分配等。 - Charles Salvia

2

BYTE就是typedef unsigned char BYTE;

您可以轻松地使用以下任何构造函数

string ( const char * s, size_t n );
string ( const char * s );

2
这里是完整的代码。
#include <bits/stdc++.h>

using namespace std;

typedef unsigned char BYTE;

int main() {
  //method 1;
  std::vector<BYTE> data = {'H','E','L','L','O','1','2','3'};
  //string constructor accepts only const char
  std::string s((const char*)&(data[0]), data.size());
  std::cout << s << std::endl;

  //method 2
  std::string s2(data.begin(),data.end());
  std::cout << s2 << std::endl;

  //method 3
  std::string s3(reinterpret_cast<char const*>(&data[0]), data.size()) ;
  std::cout << s3 << std::endl;
 
  return 0;
}

-1

如果有访问CryptoPP的权限

可读的十六进制字符串转换为无符号字符

std::string& hexed = "C23412341324AB";
uint8_t      buffer[64] = {0};
StringSource ssk(hexed, true,
            new HexDecoder(new ArraySink(buffer,sizeof(buffer))));

然后返回

std::string hexed;
uint8_t val[32]  = {0};
StringSource ss(val, sizeof(val), true,new HexEncoder(new StringSink(hexed));
// val == buffer

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