C++處理中文的問題困擾我很久了。之前一旦遇到中文基本就投諸java懷抱了。 今天看到一個漂亮的c++程式,遂豁然開朗。總結一下分享給大家: 問題描述: c++ 中 char*/string 形式的字串無法正確的對中文字串進行處理(如 find, strlen, substr 等常規操作) 。 比如當你在char* 中 find 英文逗號時,有可能匹配的不只是逗號,還找到了某個漢字的一個位元組,而你無法在char*中區分它們。 問題原因: 中文字元長度不固定,按位元組處理往往出現亂碼或錯誤分割。在unicode中每個中文為2個位元組,而中文中間夾雜的英文和半形標點則仍然是1個位元組。 解決方案: 構造三層邏輯結構:輸入層、邏輯處理層、輸出層。 -- 輸入層接收char*輸入,並將其轉換為wchar*. -- 邏輯處理層在 wchar* 或 wstring 的基礎上進行字串操作,此時操作最小單位為中文字元,不會再有亂碼。 -- 輸出層將wchar*的結果再次轉換為char* ,返回給外部。 這樣,對外部來說,仍然是輸入char*, 輸出char*, 但在這個過程中不再有分割漢字的操作或亂碼。 核心轉碼: #include<wchar.h> wchar_t * MBCS2Unicode(wchar_t * buff, const char * str) { wchar_t * wp = buff; char * p = (char *)str; while(*p) { if(*p & 0x80) { *wp = *(wchar_t *)p; p++; } else{ *wp = (wchar_t) *p; } wp++; p++; } *wp = 0x0000; return buff; } char * Unicode2MBCS(char * buff, const wchar_t * str) { wchar_t * wp = (wchar_t *)str; char * p = buff, * tmp; while(*wp){ tmp = (char *)wp; if(*wp & 0xFF00){ *p = *tmp; p++;tmp++; *p = *tmp; p++; } else{ *p = *tmp; p++; } wp++; } *p = 0x00; return buff; } wstring str2wstr(string str) { size_t len = str.size(); wchar_t * b = (wchar_t *)malloc((len+1)*sizeof(wchar_t)); MBCS2Unicode(b,str.c_str()); wstring r(b); free(b); return r; } string wstr2str(wstring wstr) { size_t len = wstr.size(); char * b = (char *)malloc((2*len+1)*sizeof(char)); Unicode2MBCS(b,wstr.c_str()); string r(b); free(b); return r; } int wputs(wstring wstr) { wputs(wstr.c_str()); return 0; } int wputs(const wchar_t * wstr) { int len = wcslen(wstr); char * buff = (char *)malloc((len * 2 + 1)*sizeof(char)); Unicode2MBCS(buff,wstr); printf("%s",buff); free(buff); return 0; } ============================================= (另外大家關心的UTF8如何轉換,添加一段轉自End2012的UTF8--Unicode轉換程式) wchar_t * UTF8ToUnicode( const char* str )
{
int textlen ;
wchar_t * result;
textlen = MultiByteToWideChar( CP_UTF8, 0, str,-1, NULL,0 );
result = (wchar_t *)malloc((textlen+1)*sizeof(wchar_t));
memset(result,0,(textlen+1)*sizeof(wchar_t));
MultiByteToWideChar(CP_UTF8, 0,str,-1,(LPWSTR)result,textlen );
return result;
}
char * UnicodeToUTF8( const wchar_t* str )
{
char* result;
int textlen;
textlen = WideCharToMultiByte( CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL );
result =(char *)malloc((textlen+1)*sizeof(char));
memset(result, 0, sizeof(char) * ( textlen + 1 ) );
WideCharToMultiByte( CP_UTF8, 0, str, -1, result, textlen, NULL, NULL );
return result;
} ========================================== 原創帖,歡迎評論交流。轉載請註明出處。 |