文章转载自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;
}