Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 宽图表多字节不';我不能在酒里工作_C++_C++11_Winapi_Wine - Fatal编程技术网

C++ 宽图表多字节不';我不能在酒里工作

C++ 宽图表多字节不';我不能在酒里工作,c++,c++11,winapi,wine,C++,C++11,Winapi,Wine,我试图使用WideChartMultiByte将std::wstring转换为utf8 std::string。这是我的密码: const std::wstring & utf16("lorem ipsum"); // input if (utf16.empty()) { return ""; } cout << "wstring -> string, input: , size: " << utf16.size() << endl;

我试图使用WideChartMultiByte将std::wstring转换为utf8 std::string。这是我的密码:

const std::wstring & utf16("lorem ipsum"); // input

if (utf16.empty()) {
    return "";
}
cout << "wstring -> string, input: , size: " << utf16.size() << endl;
for (size_t i = 0; i < utf16.size(); ++i) {
    cout << i << ": " << static_cast<int>(utf16[i]) << endl;
}
for (size_t i = 0; i < utf16.size(); ++i) {
    wcout << static_cast<wchar_t>(utf16[i]);
}
cout << endl;
std::string res;
int required_size = 0;
if ((required_size = WideCharToMultiByte(
    CP_UTF8,
    0,
    utf16.c_str(),
    utf16.size(),
    nullptr,
    0,
    nullptr,
    nullptr
)) == 0) {
    throw std::invalid_argument("Cannot convert.");
}
cout << "required size: " << required_size << endl;
res.resize(required_size);
if (WideCharToMultiByte(
    CP_UTF8,
    0,
    utf16.c_str(),
    utf16.size(),
    &res[0],
    res.size(),
    nullptr,
    nullptr
) == 0) {
    throw std::invalid_argument("Cannot convert.");
}
cout << "Result: " << res << ", size: " << res.size() << endl;
for (size_t i = 0; i < res.size(); ++i) {
    cout << i << ": " << (int)static_cast<uint8_t>(res[i]) << endl;
}
exit(1);
return res;
我不明白为什么会有空字节。我做错了什么?

总结评论:

只要
WideCharToMultiByte
逻辑和参数正确,您的代码就是正确的;唯一的实际问题是
utf16
的初始化,需要使用较宽的文本进行初始化。代码给出了VC++2015 RTM和Update 1的预期结果,因此这是您正在使用的
WideChartMultiByte
仿真层中的一个bug

也就是说,对于C++11以后的版本,如果可能的话,有一个可移植的解决方案,您应该更喜欢:与

#包括
#包括
#包括
#包括
#包括
std::字符串测试(std::wstring const和utf16)
{

std::wcout您使用的编译器/标准库是什么?我无法使用VC++2015 Update 1复制,而只能获得所需的输出。在任何情况下,由于您将此标记为
c++11
,正确的方法是使用.wineg++。因此,您认为该代码是正确的,并且在VC 2015中确实有效?也许我应该向wine提交错误报告因此,人们实际上,代码看起来是正确的(除了初始化
utf16
,它应该使用较宽的文字),并且可以在Windows上正常工作。:-]@ildjarn ok,非常感谢您的检查:)
wstring -> string, input: , size: 11
0: 108
1: 111
2: 114
3: 101
4: 109
5: 32
6: 105
7: 112
8: 115
9: 117
10: 109
lorem ipsum
required size: 11
Result: lorem , size: 11
0: 108
1: 0
2: 111
3: 0
4: 114
5: 0
6: 101
7: 0
8: 109
9: 0
10: 32
#include <cstddef>
#include <string>
#include <locale>
#include <codecvt>
#include <iostream>

std::string test(std::wstring const& utf16)
{
    std::wcout << L"wstring -> string, input: " << utf16 << L", size: " << utf16.size() << L'\n';
    for (std::size_t i{}; i != utf16.size(); ++i)
        std::wcout << i << L": " << static_cast<int>(utf16[i]) << L'\n';
    for (std::size_t i{}; i != utf16.size(); ++i)
        std::wcout << utf16[i];
    std::wcout << L'\n';

    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> cvt;
    std::string res = cvt.to_bytes(utf16);
    std::wcout << L"Result: " << res.c_str() << L", size: " << res.size() << L'\n';
    for (std::size_t i{}; i != res.size(); ++i)
        std::wcout << i << L": " << static_cast<int>(res[i]) << L'\n';
    return res;
}

int main()
{
    test(L"lorem ipsum");
}