色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

關于C++編碼的轉換

工程師 ? 來源:CSDN ? 作者:FlushHip ? 2020-10-16 11:57 ? 次閱讀

【CPP開發者導讀】:在處理東方語言(中日韓)時,經常會遇到各種編碼問題,而且被這類問題搞的暈頭轉向。到網上查資料,看的也是一頭霧水,最后往往是誤打誤撞的把問題解決了,自己仍然稀里糊涂。

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

以下是正文

C++的項目,字符編碼是一個大坑,不同平臺之間的編碼往往不一樣,如果不同編碼格式用一套字符讀取格式讀取就會出現亂碼。因此,一般都是轉化成UTF-8這種平臺通用,且支持性很好的編碼格式。

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

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

不同的國家和地區制定了不同標準,由此產生了 GB2312、GBK、GB18030、Big5、Shift_JIS 等各自的編碼標準。這些使用多個字節來代表一個字符的各種漢字延伸編碼方式,稱為 ANSI 編碼。在簡體中文Windows操作系統,ANSI 編碼代表 GBK 編碼;在繁體中文Windows操作系統,ANSI編碼代表Big5;在日文Windows操作系統,ANSI 編碼代表 Shift_JIS 編碼。

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

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

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

因此,接下來就聊聊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是多字節字符串(multibyte string),而Unicode是寬字符字符串(wchar_t string)。

而C++11提供了wstring_convert這個類,這個類可以在wchar_t string和multibyte string之間來回轉換;

而codecvt_utf8可以提供UTF-8的編碼規則。這個類在#include 《codecvt》中。有了wstring_convert提供寬字符字符串到多字節字符串的轉化,而這個轉換規則由codecvt_uft8提供。這樣子就可以實現UTF8和Unicode的互相轉換。

從UTF8到Unicode調用成員函數wstring_convert::from_bytes;

從Unicode到UTF8調用成員函數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;}

標準庫提供了wcsrtombs和mbsrtowcs這兩個函數,當然C的標準庫也提供了這兩個函數。

講下wcsrtombs,這個函數把寬字符串轉成多字節字符串。編碼規則受地域的LC_CTYPE影響。因此這個函數可以用于本地碼的轉化(和本地的編碼息息相關)。

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

setlocale(LC_CTYPE, “”);

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

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

當然,你也可以在setlocale中指定一些編碼規則,把wcsrtombs用于別的編碼轉化,但是,這里不推薦,因為setlocale是全局的,設置了這個就會影響其他地方的編碼。

wcsrtombs的四個參數分別代表什么意思呢?

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

dst,轉化后的結果存入dst指向的內存;

src,待轉化的字符串的指針的指針;

len,dst指向內存的可用字節數;

ps,轉換的狀態,一般默認初始化就好了;

return type,轉化后結果的長度,不包含\0。

注意:如果dst == nullptr,這個時候wcstombs的返回值表示會有這么多字節的結果產生,因此,我們可以拿到這個返回值去新建一個數組來存儲new char[len + 1]。所以,一般調用兩次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));}

總結

C++11的標準庫還是挺強大的,雖然這么強大,但是很多特性還不了解,因此還是要多擴寬自己的視野,不然有好東西都不知道用,那就棒槌了。

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

作者:FlushHip

來源:CSDN

責任編輯:haq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 編程
    +關注

    關注

    88

    文章

    3614

    瀏覽量

    93686
  • 編碼
    +關注

    關注

    6

    文章

    942

    瀏覽量

    54814
  • C++
    C++
    +關注

    關注

    22

    文章

    2108

    瀏覽量

    73623
收藏 人收藏

    評論

    相關推薦

    C語言和C++中結構體的區別

    同樣是結構體,看看在C語言和C++中有什么區別?
    的頭像 發表于 10-30 15:11 ?199次閱讀

    C7000優化C/C++編譯器

    電子發燒友網站提供《C7000優化C/C++編譯器.pdf》資料免費下載
    發表于 10-30 09:45 ?0次下載
    <b class='flag-5'>C</b>7000優化<b class='flag-5'>C</b>/<b class='flag-5'>C++</b>編譯器

    OpenVINO2024 C++推理使用技巧

    很多人都使用OpenVINO新版的C++ 或者Python的SDK,都覺得非常好用,OpenVINO2022之后的版本C++ SDK做了大量的優化與整理,已經是非常貼近開發的使用習慣與推理方式。與OpenCV的Mat對象對接方式更是幾乎無縫對接,非常的方便好用。
    的頭像 發表于 07-26 09:20 ?884次閱讀

    c++編譯后鏈接失敗的原因?如何解決?

    /c++項目,將剛才新建的項目轉換c++項目。 完成后點擊編譯,此時也是正常的。 新建一個cpp文件,將原項目的main.c中內容全部拷貝到新建的cpp文件中保存,然后刪除原main
    發表于 07-25 08:13

    C++語言基礎知識

    電子發燒友網站提供《C++語言基礎知識.pdf》資料免費下載
    發表于 07-19 10:58 ?7次下載

    C++中實現類似instanceof的方法

    C++有多態與繼承,但是很多人開始學習C++,有時候會面臨一個常見問題,就是如何向下轉型,特別是不知道具體類型的時候,這個時候就希望C++ 可以向Java或者Python中有instanceof這個
    的頭像 發表于 07-18 10:16 ?574次閱讀
    <b class='flag-5'>C++</b>中實現類似instanceof的方法

    keil用c++編譯含有rtos模塊時的錯誤問題怎么解決?

    thePool = pvPortMalloc(sizeof(os_pool_cb_t));由于不懂c++,查閱資料得知c99編譯器是允許暗含轉換的,但是c++不允許,因此出現錯誤。我的
    發表于 05-09 08:29

    鴻蒙OS開發實例:【Native C++

    使用DevEco Studio創建一個Native C++應用。應用采用Native C++模板,實現使用NAPI調用C標準庫的功能。使用C標準庫hypot接口計算兩個給定數平方和的平
    的頭像 發表于 04-14 11:43 ?2594次閱讀
    鴻蒙OS開發實例:【Native <b class='flag-5'>C++</b>】

    使用 MISRA C++:2023? 避免基于范圍的 for 循環中的錯誤

    在前兩篇博客中,我們?向您介紹了新的 MISRA C++ 標準?和?C++ 的歷史?。在這篇博客中,我們將仔細研究以 C++ 中?for?循環為中心的特定規則。
    的頭像 發表于 03-28 13:53 ?787次閱讀
    使用 MISRA <b class='flag-5'>C++</b>:2023? 避免基于范圍的 for 循環中的錯誤

    c語言,c++,java,python區別

    C語言、C++、Java和Python是四種常見的編程語言,各有優點和特點。 C語言: C語言是一種面向過程的編程語言。它具有底層的特性,能夠對計算機硬件進行直接操作。
    的頭像 發表于 02-05 14:11 ?2370次閱讀

    vb語言和c++語言的區別

    VB語言和C++語言是兩種不同的編程語言,雖然它們都屬于高級編程語言,但在設計和用途上有很多區別。下面將詳細比較VB語言和C++語言的區別。 設計目標: VB語言(Visual Basic)是由
    的頭像 發表于 02-01 10:20 ?2262次閱讀

    C++在Linux內核開發中從爭議到成熟

    Linux 內核郵件列表中一篇已有六年歷史的老帖近日再次引發激烈討論 —— 主題是建議將 Linux 內核的開發語言從 C 轉換為更現代的 C++
    的頭像 發表于 01-31 14:11 ?623次閱讀
    <b class='flag-5'>C++</b>在Linux內核開發中從爭議到成熟

    C++簡史:C++是如何開始的

    MISRA C++:2023,MISRA? C++ 標準的下一個版本,來了!為了幫助您做好準備,我們介紹了 Perforce 首席技術支持工程師 Frank van den Beuken 博士撰寫
    的頭像 發表于 01-11 09:00 ?582次閱讀
    <b class='flag-5'>C++</b>簡史:<b class='flag-5'>C++</b>是如何開始的

    基于C/C++面向對象的方式封裝socket通信類流程簡析

    在掌握了基于 TCP 的套接字通信流程之后,為了方便使用,提高編碼效率,可以對通信操作進行封裝,本著有淺入深的原則,先基于 C 語言進行面向過程的函數封裝,然后再基于 C++ 進行面向對象的類封裝。
    的頭像 發表于 12-26 10:00 ?1815次閱讀

    基于C/C++面向對象的方式封裝socket通信類

    在掌握了基于 TCP 的套接字通信流程之后,為了方便使用,提高編碼效率,可以對通信操作進行封裝,本著有淺入深的原則,先基于 C 語言進行面向過程的函數封裝,然后再基于 C++ 進行面向對象的類封裝。
    的頭像 發表于 12-26 09:57 ?1332次閱讀
    主站蜘蛛池模板: 色大姐综合网| 动漫美女被h动态图| 骚妇BB双飞插| 青柠电影在线看| 国产九九熟女在线视频| 97成人在线| 亚洲精品国产一区二区贰佰信息网| 男人和女人全黄一级毛片| 国产在线观看免费| 菠萝菠萝蜜免费播放高清| 影音先锋色小姐| 香蕉水蜜桃牛奶涩涩| 秋葵app秋葵官网18在线观看| 久久精品国产免费播高清无卡| 国产成人免费手机在线观看视频| 99久久久国产精品免费调教| 伊人精品影院一本到综合| 翁公吮她的花蒂和奶水| 情欲.美女高潮| 欧美 亚洲 有码中文字幕| 久久99国产精品无码AV| 国产精品久久欧美一区| 被窝伦理电影午夜| 99精品欧美一区二区三区美图| 妖精视频免费看| 亚洲国产日韩欧美视频二区| 色偷偷综合网| 日本无码毛片一区二区手机看| 男女生爽爽爽视频免费观看 | 久久成人午夜电影mp4| 国产精品久久久久久久久久免费| chaopeng 在线视频| 97午夜精品| 100国产精品人妻无码| 伊人久久综合影院| 一区二区三区无码高清视频| 亚洲国产精品嫩草影院| 小草影院免费| 亚洲国产成人99精品激情在线| 午夜在线视频国产极品片 | 国产短视频精品区|