我从HTTP服务器响应中收到正文字节,我不知道如何将它们转换为UTF8字符串以便与它们一起使用。
我有一个想法,但我不确定它是否有效。我需要获取响应的字节并搜索它们并修改它们,因此我需要将std::vector<BYTE>
转换为std::wstring
或std::string
。
响应的UTF8中的字节编码位于我的std::vector<BYTE>
中,如何将它们转换为std::string
?我应该将它们转换为std::wstring
吗?
我找到了这段代码:
std::string Encoding::StringToUtf8(const std::string& str)
{
INT size = MultiByteToWideChar(CP_ACP, MB_COMPOSITE, str.c_str(), str.length(), NULL, 0);
std::wstring utf16_str(size, '\0');
MultiByteToWideChar(CP_ACP, MB_COMPOSITE, str.c_str(), str.length(), &utf16_str[0], size);
INT utf8_size = WideCharToMultiByte(CP_UTF8, 0, utf16_str.c_str(), utf16_str.length(), NULL, 0, NULL, NULL);
std::string utf8_str(utf8_size, '\0');
WideCharToMultiByte(CP_UTF8, 0, utf16_str.c_str(), utf16_str.length(), &utf8_str[0], utf8_size, NULL, NULL);
return utf8_str;
}
但是现在如果我想搜索字符串中的“Ñ”这样的字符会起作用吗?或者我要转换std::wstring
中的字节并搜索“Ñ”修改std::wstring
并将其转换为std::string
?
这两个中的哪一个是正确的?
我需要将UTF8响应放在std::string
或std::wstring
中,以便搜索和修改数据(带有特殊字符),然后以UTF8重新发送对客户端的响应。
答案 0 :(得分:4)
在std::string
中存储utf-8只不过是在“vector”中存储字节序列。 std::string
无法识别任何编码内容,任何成员函数(如find
或<algorithm>
函数如std::find
一旦您需要超出标准ASCII,就无法运行。因此,由您决定如何处理这种情况,您可以尝试将输入(L"Ñ"
)转换为utf-8序列,并尝试在std::string
中找到它,或者您可以转换string
1}}到wstring
并直接在其上工作。恕我直言,在您需要操作(搜索,提取单词,按字母或替换,以及所有这些超出ASCII范围)输入时,您最好坚持wstring
并在将其发布到客户端之前转换为utf- 8 std::string
来自EDIT001:截至评论中提到的std::codecvt_utf8
以及关于效果问题的评论。这是测试
std::wstring foo(const std::string& input)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
return converter.from_bytes(input.c_str());
}
std::wstring baz(const std::string& input)
{
std::wstring retVal;
auto targetSize = MultiByteToWideChar(CP_UTF8, 0, input.c_str(), static_cast<int>(input.size()), NULL, 0);
retVal.resize(targetSize);
auto res = MultiByteToWideChar(CP_UTF8, 0, input.c_str(), static_cast<int>(input.size()),
const_cast<LPWSTR>(retVal.data()), targetSize);
if(res == 0)
{
// handle error, throw, do something...
}
return retVal;
}
int main()
{
std::string input = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut "
"labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco "
"laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in "
"voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat "
"cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
{
auto start = std::chrono::high_resolution_clock::now();
for(int i = 0; i < 100'000; ++i)
{
auto result = foo(input);
}
auto end = std::chrono::high_resolution_clock::now();
auto res = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
std::cout << "Elapsed time: " << res << std::endl;
}
{
auto start = std::chrono::high_resolution_clock::now();
for(int i = 0; i < 100'000; ++i)
{
auto result = baz(input);
}
auto end = std::chrono::high_resolution_clock::now();
auto res = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
std::cout << "Elapsed time: " << res << std::endl;
}
return 0;
}
编译并运行为Release x64时的结果 经历时间:3065 经历时间:29
两个数量级......
答案 1 :(得分:0)
我从HTTP服务器响应中收到正文字节,我不知道如何将它们转换为UTF8字符串以便与它们一起使用。
您需要按照以下步骤操作:
第四步显然是最不重要的一步。确切的实现取决于您要转换的编码。对于我的答案来说,它太宽泛了。
使用现有实现通常具有成本效益,因此您不必自己执行步骤2-4。标准库具有非常有限的转换选项(仅在不同的unicode格式之间,以及本机窄和本机范围之间),因此您可能不能依赖它。
所以我需要将std :: vector转换为std :: wstring
将UTF-8编码字符存储在宽字符串中是没有意义的,因为UTF-8是一种窄字符编码。
但是现在如果我想在字符串中搜索像“Ñ”这样的字符会起作用吗?
当然,尽管请记住C ++标准库的字符串算法不考虑编码,因此它可能不是实现搜索的选项。特别是如果您希望搜索由多个代码点组成的任意字形集群。要正确搜索UTF-8字符串中的任何UTF-8字符,您需要:
第四步显然是最不重要的一步。确切的实现取决于搜索所需的语义类型。对于我的答案来说,它太宽泛了。
使用现有的实现通常具有成本效益,因此您不必自己完成步骤3-4。