ANSI與Unicode的轉換


最近遇到中文路徑訪問的問題,又重新學習了一遍ansi與Unicode的知識,博文記錄下來以供后續參考。

 

ANSI 編碼

ANSI一種字符代碼,為使計算機支持更多語 言,通常使用0x80~0xFF 范圍的2 個字節來表示1 個字符。不同的國家和地區制定了不同的標准,由此產生了GB2312、GBK、GB18030、Big5、Shift_JIS 等各自的編碼標准。 這些使用多個字節來代表一個字符的各種漢字延伸編碼方式,稱為ANSI 編碼。

 

關於MBCS字符集(Multi Byte Character System):GB2312、GBK等編碼被稱為MBCS,MBCS同ASCII是完全兼容的。對於前ASCII的128個字符,在MBCS字符集下有完全相同的編碼,而漢字等字符用多個字節存儲。也意味着MBCS下,字符的長度有可能有1個字節的,也有多個字節的。

 

所以ANSI編碼其實是一個統稱,不同的語言使用不同的編碼規范,並沒有跨語言統一編碼。比如 windows7 notepad記事本保存的時候,在彈出對話框的下方有“編碼”下拉框,默認是“ANSI”,也可以選擇“Unicode”(其實是UTF-16)和 “UTF-8”。如果選擇了ANSI,那么實際使用的編碼規范就跟你的操作系統版本強相關了,如果是簡體中文的windows就會用GBK標准。

 

Unicode編碼

就是把地球上所有的語言的符號,都用統一的字符集來表示,一個編碼真正做到了唯一。Unicode只是確定了字符的二進制編碼,但並沒有確定字符存儲的具體實現方式。比如UTF-8 ,UTF16是常見的Unicode實現方式。

 

UTF-8編碼是變長的,一個字符可能是1個字節,2個字節,3個字節或者4個字節長。一般來說,歐洲的字母字符長度為1到2個字節,而亞洲的大部分字符則是3個字節,附加字符為4個字節長。Unix平台中普遍支持UTF-8字符集,HTML和大多數瀏覽器也支持UTF-8。

 

UTF-16編碼的字符,要么是2個字節,要么是4個字節表示的。windows2000以上版本使用UTF-16,老版本windows用的ANSI。

 

VC下的格式轉換

ANSI字符串轉Unicode(windows下對應UTF-16編碼)
在vc工程選擇unicode編譯的情況下,如果是字符串常量可以直接使用L和_T or _TEXT宏,也可以使用wsprintf函數進行轉換(需要引用Windows.h)。
    TCHAR szW[ 100];  
     // all strings are Unicode  
    swprintf(szW,L " %s ",L " Unicode Str中文 ");  
    CString name = _T( " Report.txt ");  
      
     // ANSI to Unicode,wsprintf可以直接用,使用大寫的%S  
    
// 注意swprintf函數是不行的,據說要先加setlocale(LC_CTYPE, "chs")語句  
    wsprintfW(szW,L " %S ", " Unicode Str中文 "); 

 

如果是字符串變量,使用ATL 提供的字符轉換宏會比較方便,也可以使用wsprintf函數。
     char buff[ 512];  
     // 獲取工作目錄的路徑,ANSI編碼,路徑中的中文字符占用2個字節  
    std:: string s_currPath = _getcwd(buff, 512);  
      
    TCHAR szW[ 512];  
    USES_CONVERSION;  
     // 注意使用A2W宏,不可直接調用swprintf_s(szW,512,L"%S",...)  
    swprintf_s(szW, 512,L " %s ",A2W(s_currPath.c_str()));  
     // wsprintf可以直接使用
    wsprintfW(szW,L " %S ",s_currPath.c_str()); 

 

Unicode轉ANSI
和上面類似,使用ATL的宏W2A即可。或者使用wsprintfA(sA, "%S", L"中文"),其中sA是char數組。
另外,轉換還可以使用功能更強大的WideCharToMultiByte函數和MultiByteToWideChar函數。

 

C++11與Unicode
C++11對Unicode提供了語言級別和庫級別的支持,可以進行Unicode下不同編碼方式的轉換,我也沒玩過,可以參考這篇blog:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM