CString轉char*/wchar_t* 轉 char*

因爲程序中需要把CString轉爲char*來使用,沒想到轉換的套路挺深所以也順便記錄一下。

一般來說普通的情況只需要這樣就能轉換:

	CString strFilepath = _T("d:\\新建文件夾");
	char *pFilepath = strFilepath.GetBuffer(0);
CString自身就有提供方法進行轉換。

但是如果你的工程設置的是Unicode字符集:


編譯時就會提示例如“不能從wchar_t*轉換爲char*”等錯誤。

那就再找找unicode字符轉換成多字節字符的方法唄。


總的來說找到兩種方法,分別是C和C++的:

1.wcstombs_s函數(C下)

(Wide Const String To Multiple Byte String)

相對的也有mbstowcs_s

頭文件<stdlib.h>

函數原型 : errno_t wcstombs_s( size_t *pReturnValue, char *mbstr, size_t sizeInBytes, const wchar_t *wcstr, size_t count );

pReturnValue代表該次wchar_t轉換成char*後其字符個數;

mbstr代表接收轉換結果的char指針;

sizeInBytes代表轉到mbstr的字節數(mbstr是提前已經分配好空間的,因此它做的不是單純複製了一個首地址,而是完整內容的複製,正式點叫做深度拷貝吧);

wcstr代表要進行轉換的wchar_t*字符串;

count就是一個限制器,代表最多能存進mbstr內的字節數(如果你不想做限制,那就直接設置成_TRUNCATE吧);

如果轉換成功返回值爲0,否則就爲以下的幾項:

error code:
#define EINVAL 22
#define ERANGE 34
#define EILSEQ 42
#define STRUNCATE 80

	CString strFilepath = _T("d:\\新建文件夾");

	size_t iLengh = strFilepath.GetLength() * 2 + 1;
	size_t iConverted = 0;

	char * pFilepath = new char[iLengh];

	wcstombs_s(&iConverted, pFilepath, iLengh, strFilepath, _TRUNCATE);
注意:因爲一箇中文佔兩個字節,所以如果你直接設置iLengh = strFilepath.GetLength() + 1的話,估計得到的pFilepth中存儲的就是"d:\\新建□"等之類的東西了。

這裏直接設置爲兩倍加1是爲了應付最極端的情況:都是中文。


2.WideCharToMultiByte函數(C++下)

頭文件<winnls.h>

函數原型 : 

int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, 
int cchMultiByte, LPCSTR lpDefaultChar, LPBOOL pfUsedDefaultChar);

CodePage代表轉換目標的字符集,一般來說直接用CP_ACP(當前系統ANSI代碼頁)就行了;

其他你要看看也可以:(來源於網上http://blog.sina.com.cn/s/blog_55a406730100rgtt.html)

CP_ACP 當前系統ANSI代碼頁
CP_MACCP 當前系統Macintosh代碼頁
CP_OEMCP 當前系統OEM代碼頁,一種原始設備製造商硬件掃描碼
CP_SYMBOL Symbol代碼頁,用於Windows 2000及以後版本
CP_THREAD_ACP 當前線程ANSI代碼頁,用於Windows 2000及以後版本
CP_UTF7 UTF-7,設置此值時lpDefaultChar和lpUsedDefaultChar都必須爲NULL
CP_UTF8 UTF-8,設置此值時lpDefaultChar和lpUsedDefaultChar都必須爲NULL

dwFlags指定如何處理那些無法轉換/無法匹配的字符,一般設置爲0;

lpWideCharStr代表將要處理的wchar_t字符串;

cchWideChar代表需要處理的wchar_t字符串長度,-1的話代表整個字符串都處理;

lpMultiByteStr代表接收轉換結果的char字符串,如果這個值設置爲NULL的話;

cchMultiByte代表輸出的緩衝區大小,如果爲0,lpMultiByteStr將被忽略,函數將返回所需緩衝區大小而不使用lpMultiByteStr;

lpDefaultChar代表無法匹配時替換的默認字符(一個字符,不是字符串大兄弟),一般設置爲NULL就好了;

pfUsedDefaultChar代表是否使用默認字符進行替換了,如果上面用了NULL,那這個也用NULL就行;

小技巧 : 可以把cchMultiByte設置爲0,跑一次獲取到所需空間大小,再正式調用函數完成轉換。

示例:

	CString strFilepath = _T("d:\\新建文件夾");

	//從wchar_t*轉換爲char*
	int iSize = WideCharToMultiByte(CP_ACP, 0, strFilepath.GetBuffer(0), -1, NULL, 0, NULL, NULL);
	char *pFilepath = new char[iSize + 1];
	WideCharToMultiByte(CP_ACP, 0, strFilepath.GetBuffer(0), -1, pFilepath, iSize, NULL, NULL);

之前我也嘗試過用for循環直接一個一個處理過來,畢竟一箇中文就是佔了兩個英文的字節大小,只要遇到值不在0~255範圍內的字符,那一般都是中文字符。

然後把這個寬字符拆成兩部分存在兩個char中就行了。但是這個拆的方法應該是跟字符編碼有關,我直接根據二進制位數把它拆成前8位和後8位並沒有什麼卵用。


有關於字符編碼的轉換算法就暫不深究了,老老實實先用着上面兩個轉換函數吧。

話說csdn總喜歡把一些字↑設置爲超鏈接啊,事先說明不是我弄的,大兄弟你別亂點。


總之問題解決,可喜可賀可喜可賀。



發佈了55 篇原創文章 · 獲贊 14 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章