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");
这些代码将值设置为编辑框。但是当我从 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");