Unicode字符变成问号(C++和MFC Dialog Based App)

Unicode characters become question marks (C++ and MFC Dialog Based App)

这些代码将值设置为编辑框。但是当我从 MySQL table.

检索 Unicode 字符时遇到了问题

例如,字符串 nüşabə 设置为 nüşabÉ™.

这是我的代码。

void CmysqlDlg::OnBnClickedButton3()
{
    USES_CONVERSION;

    try
    {
        mysql::MySQL_Driver *driver = new mysql::MySQL_Driver;
        Connection *dbConn;
        Statement *st;
        ResultSet *res;

        driver = mysql::get_mysql_driver_instance();
        dbConn = driver->connect("tcp://127.0.0.1:3306", "root", "connection");
        dbConn->setSchema("mfc_app_database");

        st = dbConn->createStatement();
        res = st->executeQuery("SELECT password FROM users WHERE id=1");
        string z;
        while (res->next())
        {
            //k = res->getString("username");
            //cs.Format(_T("%s"), k);
            //CString cs(k.c_str(), CP_UTF8);
            //combo.AddString(cs);
            //usernameData.SetWindowTextW(cs);

            z = res->getString("password");
            CString pass(z.c_str()/*, CP_UTF8*/);
            nameData.SetWindowTextW(pass);
        }


        delete res;
        delete st;
        delete dbConn;
        delete driver;
    }
    catch (exception e)
    {
        ofstream file("sadaasad.txt");
        file << e.what();
        file.close();
    }
}

数据库排序规则设置为 utf8_general_ci。 其实我也不知道该怎么办。。。脑残了。。。

请帮忙。谢谢

如果为 UNICODE 编译 MFC,CString will be defined as a string of wchar_t using UTF16 encoding

像您一样直接从 char* 构建 CString,仅当所有字符都在 UNICODE 的 ASCII 子集中时才有效:

  • 一旦 unicode 字符不是 ASCII,它将以 UTF8 编码为几个字节,但 CString 构造函数随后将其解释为两个不同的字符。
  • 这是 nüşabəüşə 的情况,它们在 UTF8 中每个都需要 2 个字节,并导致您的 CString 为 3比预期更长的字符。

所以当你在 char* 中有一个 UTF8 编码的字符串时,你需要使用 MultiByteToWideChar()this SO answer 中解释的那样转换它。

编辑:代码示例

而不是

        CString pass(z.c_str());

你可以这样写:

        wchar_t *p = new wchar_t[z.size()+1];  // UTF16 has same length or less thant UTF8 equivalent
        MultiByteToWideChar(
             CP_UTF8,         // CodePage,
             0,               // flags,
             z.c_str(),       // pointer to UTF8 string
             -1,              // -1 for null terminated string, size otherwise 
             p,               // destination buffer for converted wchar_t string 
             z.size()+1);        // size of buffer
        CString pass(p);
        delete p; 

请注意 MultiByteToWideChar() 及其反向 WideCharToMultiByte() 属于 Windows API 而不是 MFC。

请注意,标准 C++ 字符串具有可移植的标准转换函数:

 wstring_convert<codecvt_utf8_utf16<wchar_t>, wchar_t> conversion;
 wstring s = conversion.from_bytes(z.c_str());
 string mbs = conversion.to_bytes(L"\u00c6\u0186");