chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C++中字符編碼的轉(zhuǎn)換

工程師 ? 來源:CSDN ? 作者:FlushHip ? 2020-10-15 10:21 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

作者:FlushHip

在處理東方語言(中日韓)時(shí),經(jīng)常會(huì)遇到各種編碼問題,而且被這類問題搞的暈頭轉(zhuǎn)向。到網(wǎng)上查資料,看的也是一頭霧水,最后往往是誤打誤撞的把問題解決了,自己仍然稀里糊涂。

這篇文章介紹了如何在最常見的編碼方式(Unicode, UTF-8, ANSI)之間進(jìn)行轉(zhuǎn)換,結(jié)合代碼實(shí)例,清晰明了,方便讀者理解,例子也可以直接拿來使用。本文推薦給經(jīng)常對(duì)文字字符串進(jìn)行處理的程序員閱讀,使其掌握字符轉(zhuǎn)換的一些基本方法。

正文

C++的項(xiàng)目,字符編碼是一個(gè)大坑,不同平臺(tái)之間的編碼往往不一樣,如果不同編碼格式用一套字符讀取格式讀取就會(huì)出現(xiàn)亂碼。因此,一般都是轉(zhuǎn)化成UTF-8這種平臺(tái)通用,且支持性很好的編碼格式。

Unicode、UTF-8的概念不做過多解釋,這里說一下ANSI,我第一次看到這個(gè)名詞,我看成了ASCII。被Mentor狠批一頓。

ANSI是一種字符代碼,為使計(jì)算機(jī)支持更多語言,通常使用 0x00 ~ 0x7F范圍的1 個(gè)字節(jié)來表示 1 個(gè)英文字符。超出此范圍使用0x80~0xFFFF來編碼,即擴(kuò)展的ASCII編碼。

不同的國(guó)家和地區(qū)制定了不同標(biāo)準(zhǔn),由此產(chǎn)生了 GB2312、GBK、GB18030、Big5、Shift_JIS 等各自的編碼標(biāo)準(zhǔn)。這些使用多個(gè)字節(jié)來代表一個(gè)字符的各種漢字延伸編碼方式,稱為 ANSI 編碼。在簡(jiǎn)體中文Windows操作系統(tǒng),ANSI 編碼代表 GBK 編碼;在繁體中文Windows操作系統(tǒng),ANSI編碼代表Big5;在日文Windows操作系統(tǒng),ANSI 編碼代表 Shift_JIS 編碼。

以上內(nèi)容摘自百度百科,可以看出,ANSI和ASCII還是有關(guān)系的。ANSI也叫本地碼。

我們要做到能在Unicode、UTF-8、ANSI這三種編碼格式中自由轉(zhuǎn)換。如下圖所示:

在C++中,要怎么做呢?當(dāng)然是用標(biāo)準(zhǔn)庫的東西啦,C++11對(duì)國(guó)際化標(biāo)準(zhǔn)做得還是可以的,提供了這些接口,正如圖中虛線所示,標(biāo)準(zhǔn)庫沒有提供UTF-8到ANSI的互相轉(zhuǎn)化接口,但是我們可以自己封轉(zhuǎn)接口,借用這條路(UTF-8 《=》 Unicode 《=》 ANSI)來實(shí)現(xiàn)。

因此,接下來就聊聊UTF8 《=》 Unicode和Unicode 《=》 ANSI。

UTF8 《=》 Unicode

先看代碼:

std::string UnicodeToUTF8(const std::wstring & wstr){ std::string ret; try { std::wstring_convert《 std::codecvt_utf8《wchar_t》 》 wcv; ret = wcv.to_bytes(wstr); } catch (const std::exception & e) { std::cerr 《《 e.what() 《《 std::endl; } return ret;}std::wstring UTF8ToUnicode(const std::string & str){ std::wstring ret; try { std::wstring_convert《 std::codecvt_utf8《wchar_t》 》 wcv; ret = wcv.from_bytes(str); } catch (const std::exception & e) { std::cerr 《《 e.what() 《《 std::endl; } return ret;}

UTF-8是多字節(jié)字符串(multibyte string),而Unicode是寬字符字符串(wchar_t string)。

而C++11提供了wstring_convert這個(gè)類,這個(gè)類可以在wchar_t string和multibyte string之間來回轉(zhuǎn)換;

而codecvt_utf8可以提供UTF-8的編碼規(guī)則。這個(gè)類在#include 《codecvt》中。有了wstring_convert提供寬字符字符串到多字節(jié)字符串的轉(zhuǎn)化,而這個(gè)轉(zhuǎn)換規(guī)則由codecvt_uft8提供。這樣子就可以實(shí)現(xiàn)UTF8和Unicode的互相轉(zhuǎn)換。

從UTF8到Unicode調(diào)用成員函數(shù)wstring_convert::from_bytes;

從Unicode到UTF8調(diào)用成員函數(shù)wstring_convert::to_bytes;

Unicode 《=》 ANSI

std::string UnicodeToANSI(const std::wstring & wstr){ std::string ret; std::mbstate_t state = {}; const wchar_t *src = wstr.data(); size_t len = std::wcsrtombs(nullptr, &src, 0, &state); if (static_cast《size_t》(-1) != len) { std::unique_ptr《 char [] 》 buff(new char[len + 1]); len = std::wcsrtombs(buff.get(), &src, len, &state); if (static_cast《size_t》(-1) != len) { ret.assign(buff.get(), len); } } return ret;}std::wstring ANSIToUnicode(const std::string & str){ std::wstring ret; std::mbstate_t state = {}; const char *src = str.data(); size_t len = std::mbsrtowcs(nullptr, &src, 0, &state); if (static_cast《size_t》(-1) != len) { std::unique_ptr《 wchar_t [] 》 buff(new wchar_t[len + 1]); len = std::mbsrtowcs(buff.get(), &src, len, &state); if (static_cast《size_t》(-1) != len) { ret.assign(buff.get(), len); } } return ret;}

標(biāo)準(zhǔn)庫提供了wcsrtombs和mbsrtowcs這兩個(gè)函數(shù),當(dāng)然C的標(biāo)準(zhǔn)庫也提供了這兩個(gè)函數(shù)。

講下wcsrtombs,這個(gè)函數(shù)把寬字符串轉(zhuǎn)成多字節(jié)字符串。編碼規(guī)則受地域的LC_CTYPE影響。因此這個(gè)函數(shù)可以用于本地碼的轉(zhuǎn)化(和本地的編碼息息相關(guān))。

因此,有關(guān)于本地碼的使用,在代碼中要加上下列語句:

setlocale(LC_CTYPE, “”);

目的是讓本地碼生效,這條代碼的作用就是讓C++語言的Locale(地域)和本地的地域相同。在Linux下可以運(yùn)行l(wèi)ocale命令看看:

可以看到,LC_CTYPE = en_US.UTF-8,這表示英文,英國(guó),UTF-8編碼,也就是說本地碼就是這個(gè)。

當(dāng)然,你也可以在setlocale中指定一些編碼規(guī)則,把wcsrtombs用于別的編碼轉(zhuǎn)化,但是,這里不推薦,因?yàn)閟etlocale是全局的,設(shè)置了這個(gè)就會(huì)影響其他地方的編碼。

wcsrtombs的四個(gè)參數(shù)分別代表什么意思呢?

std::size_t wcsrtombs( char* dst, const wchar_t** src, std::size_t len, std::mbstate_t* ps );

dst,轉(zhuǎn)化后的結(jié)果存入dst指向的內(nèi)存;

src,待轉(zhuǎn)化的字符串的指針的指針;

len,dst指向內(nèi)存的可用字節(jié)數(shù);

ps,轉(zhuǎn)換的狀態(tài),一般默認(rèn)初始化就好了;

return type,轉(zhuǎn)化后結(jié)果的長(zhǎng)度,不包含\0。

注意:如果dst == nullptr,這個(gè)時(shí)候wcstombs的返回值表示會(huì)有這么多字節(jié)的結(jié)果產(chǎn)生,因此,我們可以拿到這個(gè)返回值去新建一個(gè)數(shù)組來存儲(chǔ)new char[len + 1]。所以,一般調(diào)用兩次wcstombs。

mbsrtowcs同理。

UTF-8 《=》 ANSI

以Unicode為中介裝換便是。

std::string UTF8ToANSI(const std::string & str){ return UnicodeToANSI(UTF8ToUnicode(str));}std::string ANSIToUTF8(const std::string & str){ return UnicodeToUTF8(ANSIToUnicode(str));}

總結(jié)

C++11的標(biāo)準(zhǔn)庫還是挺強(qiáng)大的,雖然這么強(qiáng)大,但是很多特性還不了解,因此還是要多擴(kuò)寬自己的視野,不然有好東西都不知道用,那就棒槌了。

對(duì)了,在Linux下加上setlocale(LC_CTYPE, “”)后程序在命令行中可以正常顯示,不加有可能不正常顯示,原因是setlocale(LC_CTYPE, “”)也影響了cout,全局的嘛;而在CodeBlocks下不能正常顯示,不知道為什么,但是調(diào)試的過程中,觀察到了正常的結(jié)果;Visual Studio中沒有做實(shí)驗(yàn),不過應(yīng)該沒問題。

責(zé)任編輯:haq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 計(jì)算機(jī)
    +關(guān)注

    關(guān)注

    19

    文章

    7835

    瀏覽量

    93436
  • 編程
    +關(guān)注

    關(guān)注

    90

    文章

    3723

    瀏覽量

    97424
  • C++
    C++
    +關(guān)注

    關(guān)注

    22

    文章

    2124

    瀏覽量

    77351
  • UTF-8
    +關(guān)注

    關(guān)注

    0

    文章

    13

    瀏覽量

    8109
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    C++與lua聯(lián)合編程

    在現(xiàn)代軟件工程的龐大架構(gòu),純粹的 C++ 與動(dòng)態(tài)腳本語言之間的關(guān)系,早已演變成一場(chǎng)精密的“商業(yè)分工”。C++ 扮演著提供極致性能的“底層重工業(yè)”,而 Lua 則充當(dāng)著實(shí)現(xiàn)靈活業(yè)務(wù)邏輯的“輕量級(jí)
    發(fā)表于 04-19 16:27

    C++:const 的空間,常量也能占內(nèi)存?

    5g.5jh.dg8sg.cnJIWWQc++語言 c++語言5g.Zq2.dg8sg.cnJIWWQc++語言 def lock_tetromino(self): \"\"\"將落地的方塊鎖定到網(wǎng)格
    發(fā)表于 04-16 19:19

    keil實(shí)現(xiàn)cc++混合編程

    起因項(xiàng)目中使用到一個(gè)開源的模擬IIC的庫,封裝的比較好,但是是使用c++寫的。于是將其移植到自己的項(xiàng)目中,主要有以下三步操作: 在工程選項(xiàng) C/C++中去掉勾選
    發(fā)表于 01-26 08:58

    C語言與C++的區(qū)別及聯(lián)系

    缺點(diǎn):性能比面向過程低。 二、具體語言上的區(qū)別 1、關(guān)鍵字的不同 C語言有32個(gè)關(guān)鍵字;C++有63個(gè)關(guān)鍵字。 2、后綴名不同 C源文件后綴.c,
    發(fā)表于 12-24 07:23

    CC++之間的聯(lián)系

    1、語法兼容性: C++完全兼容C語言的語法,這意味著任何有效的C語言程序都可以直接在C++編譯器下編譯通過。 2、底層控制: C++
    發(fā)表于 12-11 06:51

    C語言和C++之間的區(qū)別是什么

    ,尤其是在涉及到類型轉(zhuǎn)換時(shí),會(huì)盡量防止隱式的、可能導(dǎo)致問題的類型轉(zhuǎn)換。 相比之下,C語言允許更多的靈活性,但也更容易產(chǎn)生類型相關(guān)的運(yùn)行時(shí)錯(cuò)誤,因?yàn)槠漕愋蜋z查不如C++嚴(yán)格。 3、函數(shù)
    發(fā)表于 12-11 06:23

    C/C++條件編譯

    條件編譯是一種在編譯時(shí)根據(jù)條件選擇性地包含或排除部分代碼的處理方法。在 C/C++ ,條件編譯使用預(yù)處理指令 #ifdef、#endif、#else 和 #elif 來實(shí)現(xiàn)。常用的條件編譯指令有
    發(fā)表于 12-05 06:21

    C++程序異常的處理機(jī)制

    1、什么是異常處理? 有經(jīng)驗(yàn)的朋友應(yīng)該知道,在正常的CC++編程過程難免會(huì)碰到程序不按照原本設(shè)計(jì)運(yùn)行的情況。 最常見的有除法分母為零,數(shù)組越界,內(nèi)存分配失效、打開相應(yīng)文件失敗等等。 一個(gè)程序
    發(fā)表于 12-02 07:12

    C/C++代碼靜態(tài)測(cè)試工具Perforce QAC 2025.3的新特性

    ?Perforce Validate??QAC?項(xiàng)目的相對(duì)/根路徑的支持。C++?分析也得到了增強(qiáng),增加了用于檢測(cè) C++?并發(fā)問題的新檢查,并改進(jìn)了實(shí)體名稱和實(shí)
    的頭像 發(fā)表于 10-13 18:11 ?706次閱讀
    <b class='flag-5'>C</b>/<b class='flag-5'>C++</b>代碼靜態(tài)測(cè)試工具Perforce QAC 2025.3的新特性

    終端GBK編碼顯示錯(cuò)誤的原因?怎么解決?

    STC-ISP串口助手可正常顯示,在RT-thread studio終端中使用GBK編碼顯示異常,切換UTF8會(huì)顯示例如“”的字符)。
    發(fā)表于 09-11 07:50

    技能+1!如何在樹莓派上使用C++控制GPIO?

    和PiGPIO等庫,C++可用于編程控制樹莓派的GPIO引腳。它提供了更好的性能和控制能力,非常適合對(duì)速度和精度要求較高的硬件項(xiàng)目。在樹莓派社區(qū),關(guān)于“Python
    的頭像 發(fā)表于 08-06 15:33 ?4454次閱讀
    技能+1!如何在樹莓派上使用<b class='flag-5'>C++</b>控制GPIO?

    Perforce QAC產(chǎn)品簡(jiǎn)介:面向C/C++的靜態(tài)代碼分析工具(已通過SO 26262認(rèn)證)

    Perforce QAC專為C/C++開發(fā)者打造,支持多種編碼規(guī)范、功能安全標(biāo)準(zhǔn)(ISO 26262)等,廣泛用于汽車、醫(yī)療、嵌入式開發(fā)領(lǐng)域,可幫助快速識(shí)別關(guān)鍵缺陷、提升代碼質(zhì)量、實(shí)現(xiàn)合規(guī)交付。
    的頭像 發(fā)表于 07-10 15:57 ?1438次閱讀
    Perforce QAC產(chǎn)品簡(jiǎn)介:面向<b class='flag-5'>C</b>/<b class='flag-5'>C++</b>的靜態(tài)代碼分析工具(已通過SO 26262認(rèn)證)

    在OpenVINO? C++代碼啟用 AddressSanitizer 時(shí)的內(nèi)存泄漏怎么解決?

    在 OpenVINO? C++代碼啟用 AddressSanitizer 時(shí)遇到內(nèi)存泄漏: \"#0 0xaaaab8558370 in operator new(unsigned
    發(fā)表于 06-23 07:16

    《ESP32S3 Arduino開發(fā)指南》第三章 C/C++語言基礎(chǔ)

    基礎(chǔ),由于篇幅有限,在此僅對(duì)C/C++語言基礎(chǔ)進(jìn)行簡(jiǎn)單介紹。本章將分為如下9個(gè)小節(jié):3.1 數(shù)據(jù)類型3.2 運(yùn)算符3.3 表達(dá)式3.4 數(shù)組3.5 字符串3.6 注釋3.7 順序結(jié)構(gòu)3.8 選擇結(jié)構(gòu)
    發(fā)表于 06-10 09:20

    主流的 MCU 開發(fā)語言為什么是 C 而不是 C++?

    在單片機(jī)的地界兒里,C語言穩(wěn)坐中軍帳,C++想分杯羹?難嘍。咱電子工程師天天跟那針尖大的內(nèi)存空間較勁,C++那些花里胡哨的玩意兒,在這兒真玩不轉(zhuǎn)。先說內(nèi)存這道坎兒。您當(dāng)stm32f4的256kRAM
    的頭像 發(fā)表于 05-21 10:33 ?1186次閱讀
    主流的 MCU 開發(fā)語言為什么是 <b class='flag-5'>C</b> 而不是 <b class='flag-5'>C++</b>?