c++ 中字符串編碼 轉碼


轉自:https://my.oschina.net/shelllife/blog/1827897

C/C++語言中的字符類型

存在兩種表示字符的基本類型:

  • char:一個字節8bit表示,最多表示256個字符,表示和用來處理ASCII字符集,國際通用
  • wchar_t:多字節字符表示,典型2個字節或者4個字節,如GNU libc中為4B,可以表示更多的字符,滿足國際化應用開發的需求,實現標准

在開發中ASCII編碼字符都是用char來表示,可以轉換成wchar_t表示;wchar_t類型與Unicode編碼是完全獨立的概念,不過在實現上Unicode編碼一般用wchar_t來表示實現而已,但wchar_t字符並不一定就是Unicode編碼字符。

對應兩種字符類型存在兩種字符串類型(C++):

  • string: char字符列表或者是字節列表(bytes)
  • wstring: wchar_t字符列表或者是寬子節列表

對應兩種字符類型的輸出函數流對象有:

  • sprintf/wsprintf: 分別對應char與wchar_t
  • cout/wcout:分別對應string與wstring
  • stringstream/wstringstream: 分別對應string與wstring

字符串常量

C++11標准中增加了一些表示字符串常量的標識,如下有:

  • L"您好!": wstring字符串常量,使用文件保存編碼方式字符集
  • R"(您 好 \n)": 原始字符串常量(字節數組),保留所有的字符
  • u8"您好!": string字符串常量(字節數組),使用UTF8進行編碼保存

字符集及編碼

已知有很多的字符集,比如:ASCII,UTF8,GBK,GB2312,UTF16,UTF32,UNICODE,Latin等等。常用中文字符集編碼有:

  • UTF8:又分為帶簽名和不帶簽名兩種,Windows代碼頁為65001,VS中應該選擇【UTF8-帶簽名】的格式
  • GBK/GB2312:Windows代碼頁為936
  • GB18030: Windows代碼頁為54936

小技巧:修改Windows系統中cmd命令行窗口的顯示字符集,默認字符集為OS字符集,如GBK-936。如果希望顯示UTF8字符,則可以修改:chcp 65001.

在VS項目的調試命令窗口中無法手動修改,可以通過system函數來修改:

system("C:\\Windows\\system32\\chcp 65001");// 修改終端字符集為UTF8 

源文件的編碼保存選項

可以將源文件保存成不同的編碼方式,如果文件中有中文,則必須選擇可以對中文進行編碼的字符集,如UTF8,GBK,GB2312等,否認可能會出現莫名其妙的編譯錯誤,因為文件中存在無法識別的字符內容。

在Visual Studio中,選中文件后該設置在:【文件 - 高級保存選項】中。

C++11中GBK/UTF/wchar_t之間的編碼處理轉換

在處理中文時,不同的應用場景下總是無法避免進行GBK和UTF8之間的相互轉換,C++11標識提供了<locale>和<codecvt>機制和工具來簡化處理。

借助其中的std::wstring_convert和std::codecvt_utf8模板,通過wchar_t類型為中介,可以快速地實現轉換,基本代碼如下:

/* 轉換GBK編碼的中文到UTF8編碼:GBK - WChar - UTF8兩次轉換 */ //GBK在linux下的locale名可能是"zh_CN.GBK" const char* GBK_LOCALE_NAME = ".936"; //GBK在windows下的locale name std::wstring_convert<std::codecvt_byname<wchar_t, char, mbstate_t>> Conver_GBK(new codecvt_byname<wchar_t, char, mbstate_t>(GBK_LOCALE_NAME)); //GBK - wchar_t std::wstring _wname = Conver_GBK.from_bytes(data.Name); // 輸入為char*的字符串表示或者數組,輸出為wstring std::wstring _waddr = Conver_GBK.from_bytes(data.Address);// 輸入為char*的字符串表示或者數組,輸出為wstring std::wstring _wdept = Conver_GBK.from_bytes(data.GrantDept);// 輸入為char*的字符串表示或者數組,輸出為wstring wcout << "Name: " << _wname << ",addr:" << _waddr << ",dept:" << _wdept << endl; // 將wstring轉化為UTF8編碼的字節數組string表示 std::wstring_convert<std::codecvt_utf8<wchar_t>> conv; string _name = conv.to_bytes(_wname);// 輸入為wstring字符串 string _addr = conv.to_bytes(_waddr); string _dept = conv.to_bytes(_wdept); // 將UTF8字符串轉換為GBK字符編碼表示string字節數組 std::string _name = Conver_GBK.to_bytes(conv.from_bytes(_name)); // 先轉換成wstring,然后再轉換成GBK的string std::string _addr = Conver_GBK.to_bytes(conv.from_bytes(_addr)); // 先轉換成wstring,然后再轉換成GBK的string 


免責聲明!

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



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