Unicode 字符变为问号(C++ 和基于 MFC 对话框的应用)
Unicode characters become question marks (C++ and MFC Dialog Based App)
这些代码将值设置为编辑框。但是当我从 MySQL 表中检索 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
。其实我不知道我应该怎么做...大脑停止了...
请帮忙。谢谢。
如果编译 MFC for UNICODE,CString 将被定义为使用 UTF16 编码的wchar_t
字符串。
像您一样直接从char*
构造CString
,仅当所有字符都在 UNICODE 的 ASCII 子集中时才有效:
- 一旦 unicode char 不是 ASCII,它就会在 UTF8 中编码为几个字节,但 CString 构造函数随后会将其解释为两个不同的字符。
- 对于具有
ü
、ş
和ə
的nüşabə
就是这种情况,它们都需要 2 个字节的 UTF8,并导致您的 CString 比预期长 3 个字符。
因此,当您在char*
中有一个 UTF8 编码字符串时,您需要按照此 SO 答案中的说明使用 MultiByteToWideChar()
进行转换。
编辑:代码示例
而不是
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"u00c6u0186");
相关文章:
- 如何在 MFC 对话框中使用 OnDraw
- "最小化"按钮不会出现在 MFC 对话框中
- 在网格视图中显示数据 - 基于 MFC c++ 对话框的应用程序
- MFC 对话框属性表用法在 VS 2017 中产生错误,适用于 VS 2013
- 如何在MFC对话框应用程序中默认将复选框设置为选中?
- 基于 MFC 对话框的应用程序无法调用对话框两次
- 是否可以将 MFC 对话框资源附加到 CChildView
- MFC 对话框控件的"Accept Files"选项如何工作?
- MFC对话框数据验证失败时还原数据
- 在std ::线程中打开MFC对话框
- 标准输出输出不会显示在基于 Windows MFC 对话框的应用的控制台上
- 如何在MFC对话框上绘制/创建GDI
- 根据通过/失败返回,在MFC对话框中更改LED颜色
- MFC C对话框::在x64上创建挂起
- MFC对话框应用程序未关闭
- MFC对话框成员变量的随机崩溃不在范围中
- 查找 MFC 对话框的当前位置
- 在MFC对话框应用程序中全天候检查系统时间
- 如何防止基于 MFC 对话框的应用在 ESC 键后关闭,但允许其他控件处理它
- 使用 mfc 对话框显示.bmp图像时出错