文章转载自http://blog.csdn.net/lanbing510/article/details/7425613
在VC++中,CString直接转换成const char* 有点困难,下面是自己用的一种可行方案:
从网上找了一些CString变量转换成const char*的方法,一种有效的办法是使用WideCharToMultiByte库函数进行转换。
将LPCTSTR转换为const char *,因为Unicode的问题,LPCTSTR
1、在非UNICODE环境下为 const char *
2、在UNICODE环境下为 const unsigned short *
VS2008默认的字符集是Unicode,而VC6.0默认是多字节字符集,Unicode字符集你要加_T("")或L"",你也可以“工程-属性-修改字符集”。
在情况2时需要借助API函数WideCharToMultiByte进行转换。其函数原型如下所示:
int WideCharToMultiByte(
UINT CodePage, // code page
DWORD dwFlags, // performance and mapping flags
LPCWSTR lpWideCharStr, // wide-character string
int cchWideChar, // number of chars in string
LPSTR lpMultiByteStr, // buffer for new string
int cbMultiByte, // size of buffer
LPCSTR lpDefaultChar, // default for unmappable chars
LPBOOL lpUsedDefaultChar // set when default char used
);
可以写一个将CString变量转换成char*类型转换函数如下:
//将CString变量转换成char*类型 char* CStringToCharArray(CString cStr) { char *ptr; #ifdef _UNICODE LONG len; len = WideCharToMultiByte(CP_ACP, 0, cStr, -1, NULL, 0, NULL, NULL); ptr = new char[len + 1]; memset(ptr, 0, len + 1); WideCharToMultiByte(CP_ACP, 0, cStr, -1, ptr, len + 1, NULL, NULL); #else ptr = new char[cStr.GetAllocLength() + 1]; sprintf(ptr, _T("%s"), cStr); #endif return ptr; }
总结,出现乱码的根源在于字符集编码格式不同造成的,这是就需要进行转换。
下面给出测试代码:
// MFCApplication1Test.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "MFCApplication1Test.h" #include "../InterfaceECGTest/EcgModuleFactory.h" //包含类声明头文件 #include "../HiDB/include/DB/HiDB.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // 唯一的应用程序对象 CWinApp theApp; using namespace std; //将CString变量转换成char*类型 char* CStringToCharArray(CString cStr) { char *ptr; #ifdef _UNICODE LONG len; len = WideCharToMultiByte(CP_ACP, 0, cStr, -1, NULL, 0, NULL, NULL); ptr = new char[len + 1]; memset(ptr, 0, len + 1); WideCharToMultiByte(CP_ACP, 0, cStr, -1, ptr, len + 1, NULL, NULL); #else ptr = new char[cStr.GetAllocLength() + 1]; sprintf(ptr, _T("%s"), cStr); #endif return ptr; } int main() { int nRetCode = 0; HMODULE hModule = ::GetModuleHandle(nullptr); if (hModule != nullptr) { // 初始化 MFC 并在失败时显示错误 if (!AfxWinInit(hModule, nullptr, ::GetCommandLine(), 0)) { // TODO: 更改错误代码以符合您的需要 wprintf(L"错误: MFC 初始化失败\n"); nRetCode = 1; } else { // TODO: 在此处为应用程序的行为编写代码。 ICEcgObject* p_EcgObject; p_EcgObject = EcgModuleFactory::CreateEcgObject(); p_EcgObject->SetEcgParaValue(10,20, 30); EcgModuleFactory::DestroyEcgObject(p_EcgObject); HiDB* m_DB = new HiDB(HiDBType_MSSQL, true); try { //参数形式的数据库链接字符串:"driver={SQL Server};Provider=SQLOLEDB;Server=127.0.0.1;Database=SuperHolter;uid=sa;pwd=sa" m_DB->SetConnectionString(ConfigFile, ""); bool ret = m_DB->Open(); string val = m_DB->ExecuteScalar("SELECT RoleName FROM Roles WHERE ID=%d",2); printf("角色编号为2的角色名称为:%s\n", val.c_str()); CString sql, roleName; roleName = CStringW("分析医师2");//若不使用CStringW转换,后面的格式化语句sql出现乱码,主要是由于编码格式造成的 sql.Format(_T("update Roles set RoleName='%s' where ID=%d"), roleName, 2); bool bSuccess = m_DB->ExecuteNoQuery(CStringToCharArray(sql)); printf("数据更新后,角色编号为2的角色名称为:%s\n", CStringToCharArray(roleName)); //下面的输出中如果使用string类型的数据值,也会出现乱码,因为要求数据类型为const char*,除非使用c_str函数转换为const char*类型,原因前面已做过介绍。 string roleNameTest = "分析医师1"; printf("角色编号为2的角色名称为:%s\n", roleNameTest.c_str()); //m_DB->ExecuteNoQuery("usp_Roles_getByID", 3); shared_ptr<HiDBTable> tb = m_DB->ExecuteQuery("SELECT * FROM Roles"); string colName, colValue; printf("表Roles的数据信息如下:\n"); printf("角色编号\t角色名称\n"); for (HiDBTable::iterator row = tb->begin(); row != tb->end(); ++row) { for (HiDBMap::iterator col = row->begin(); col != row->end(); col++) { colName = col->first; colValue = col->second; //cout << colValue; printf("%s\t", colValue.c_str()); } printf("\n"); } m_DB->Close(); getchar(); } catch (HiDBException& e) { // ... } getchar(); } } else { // TODO: 更改错误代码以符合您的需要 wprintf(L"错误: GetModuleHandle 失败\n"); nRetCode = 1; } return nRetCode; }