5

我正在尝试从字符串转换为 LPCWSTR(我使用多咬)。

1)例如:

LPCWSTR ToLPCWSTR(string text)
{
    LPCWSTR sw = (LPCWSTR)text.c_str();
    return sw;
}

2)这将返回中文字符:

LPCWSTR ToLPCWSTR(string text)
{
    std::wstring stemp = std::wstring(text.begin(), text.end());
    LPCWSTR sw = (LPCWSTR)stemp.c_str();
    return sw;
}

但是,它们都始终显示正方形:

图片

已编辑: 我的代码由 Barmak Shemirani 编辑

std::wstring get_utf16(const std::string &str, int codepage)
{
    if (str.empty()) return std::wstring();
    int sz = MultiByteToWideChar(codepage, 0, &str[0], (int)str.size(), 0, 0);
    std::wstring res(sz, 0);
    MultiByteToWideChar(codepage, 0, &str[0], (int)str.size(), &res[0], sz);
    return res;
}

string HttpsWebRequest(string domain, string url)
{
    LPCWSTR sdomain = get_utf16(domain, CP_UTF8).c_str();
    LPCWSTR surl = get_utf16(url, CP_UTF8).c_str();
    //(Some stuff...)
}

返回: https ://i.gyazo.com/ea4cd50765bfcbe12c763ea299e7b508.png

已编辑: 使用从 UTF8 传递到 UTF16 的另一个代码,结果仍然相同。

std::wstring utf8_to_utf16(const std::string& utf8)
{
    std::vector<unsigned long> unicode;
    size_t i = 0;
    while (i < utf8.size())
    {
        unsigned long uni;
        size_t todo;
        bool error = false;
        unsigned char ch = utf8[i++];
        if (ch <= 0x7F)
        {
            uni = ch;
            todo = 0;
        }
        else if (ch <= 0xBF)
        {
            throw std::logic_error("not a UTF-8 string");
        }
        else if (ch <= 0xDF)
        {
            uni = ch & 0x1F;
            todo = 1;
        }
        else if (ch <= 0xEF)
        {
            uni = ch & 0x0F;
            todo = 2;
        }
        else if (ch <= 0xF7)
        {
            uni = ch & 0x07;
            todo = 3;
        }
        else
        {
            throw std::logic_error("not a UTF-8 string");
        }
        for (size_t j = 0; j < todo; ++j)
        {
            if (i == utf8.size())
                throw std::logic_error("not a UTF-8 string");
            unsigned char ch = utf8[i++];
            if (ch < 0x80 || ch > 0xBF)
                throw std::logic_error("not a UTF-8 string");
            uni <<= 6;
            uni += ch & 0x3F;
        }
        if (uni >= 0xD800 && uni <= 0xDFFF)
            throw std::logic_error("not a UTF-8 string");
        if (uni > 0x10FFFF)
            throw std::logic_error("not a UTF-8 string");
        unicode.push_back(uni);
    }
    std::wstring utf16;
    for (size_t i = 0; i < unicode.size(); ++i)
    {
        unsigned long uni = unicode[i];
        if (uni <= 0xFFFF)
        {
            utf16 += (wchar_t)uni;
        }
        else
        {
            uni -= 0x10000;
            utf16 += (wchar_t)((uni >> 10) + 0xD800);
            utf16 += (wchar_t)((uni & 0x3FF) + 0xDC00);
        }
    }
    return utf16;
}
4

2 回答 2

5

你有两个问题。

  1. LPCWSTR是一个指向 的指针wchar_t,并std::string::c_str()返回一个const char*。这两种类型是不同的,所以从const char*to转换是LPCWSTR行不通的。
  2. 由返回的指针指向的内存std::basic_string::c_str归字符串对象所有,并在字符串超出范围时被释放。

您将需要分配内存并制作字符串的副本。

为新的宽字符串分配内存的最简单方法是只返回一个std::wstring. 然后,您可以将返回的指针传递c_str()给任何 API 函数LPCWSTR

std::wstring string_to_wstring(const std::string& text) {
    return std::wstring(text.begin(), text.end());
}
于 2016-07-01T23:42:45.293 回答
2

如果std::string源是英语或某些拉丁语言,则std::wstring可以通过简单的副本完成转换(如 Miles Budnek 的回答所示)。但一般来说你必须使用MultiByteToWideChar

std::wstring get_utf16(const std::string &str, int codepage)
{
    if (str.empty()) return std::wstring();
    int sz = MultiByteToWideChar(codepage, 0, &str[0], (int)str.size(), 0, 0);
    std::wstring res(sz, 0);
    MultiByteToWideChar(codepage, 0, &str[0], (int)str.size(), &res[0], sz);
    return res;
}

您必须知道用于制作源字符串的代码页。您可以使用GetACP()查找用户计算机的代码页。如果源字符串是 UTF8,则CP_UTF8用于代码页。

于 2016-07-02T01:35:42.993 回答