引言
在C++中,unsigned char *或unsigned char []是无法直接转换为std::string的,比如有下面例子:
cpp
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
int main()
{
unsigned char cbuffer[]={0x61,0x62,0x63,0x0};
string sbuffer=cbuffer; // error
cout << sbuffer << endl;
return 0;
}
编译,会发现报错:

所以该如何将unsigned char *或unsigned char []转换为std::string呢,有如下方法。
方法一、使用reinterpret_cast
通过reinterpret_cast可以进行强制类型转换:
cpp
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
int main()
{
const unsigned char cbuffer[]={0x61,0x62,0x63,0x0,0x64,0x65};
string sbuffer=reinterpret_cast<const char*>(cbuffer);
cout << sbuffer << endl;
return 0;
}
编译,运行效果如下。可以看到编译没有出错,但是std::string会丢失'\0'之后的数据,出现截断问题:

所以可以使用std::string的构造函数:string(size_type n,char c),用来创建一个包含n个元素的string对象,对象中的每个元素都被初始化为字符c。修改上述例子为:
cpp
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
int main()
{
const unsigned char cbuffer[]={0x61,0x62,0x63,0x0,0x64,0x65};
string sbuffer( reinterpret_cast<const char *>(cbuffer), sizeof(cbuffer) ) ;
cout << sbuffer << endl;
return 0;
}
编译,运行效果如下。可以看到修改例子后,解决了截断问题:

方法二、使用basic_string<unsigned char>
std::string定义在/usr/include/c++/11/bits/stringfwd.h中:
cpp
/// A string of @c char
typedef basic_string<char> string;
#ifdef _GLIBCXX_USE_WCHAR_T
/// A string of @c wchar_t
typedef basic_string<wchar_t> wstring;
#endif
#ifdef _GLIBCXX_USE_CHAR8_T
/// A string of @c char8_t
typedef basic_string<char8_t> u8string;
#endif
#if __cplusplus >= 201103L
/// A string of @c char16_t
typedef basic_string<char16_t> u16string;
/// A string of @c char32_t
typedef basic_string<char32_t> u32string;
#endif
从上面可以看到,std::string其实就是basic_string<char>。所以我们可以定义basic_string<unsigned char>为ustring:
cpp
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <bits/stdc++.h>
using namespace std;
//typedef basic_string<char> string;
typedef basic_string<unsigned char> ustring;
int main()
{
const unsigned char cbuffer[]={0x61,0x62,0x63,0x0,0x64};
ustring ustr = cbuffer;
//std::cout << ustr << std::endl; //error
printf("%s\n", ustr.c_str());
return 0;
}
编译,运行效果如下:

这种方法并不是很推荐,因为使用std::cout和其它流运算符无法打印basic_string<unsigned char>的内容。
参考
《C++ : Idiomatic way of creating string from unsigned char array》