zoukankan      html  css  js  c++  java
  • 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"(您 好 )": 原始字符串常量(字节数组),保留所有的字符
    • 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
    
  • 相关阅读:
    2014阿里巴巴面试题哈尔滨
    Hadoop分布式集群配置
    Ubuntu上搭建Hadoop环境(单机模式+伪分布模式)
    安装VMware Workstation提示the msi failed的解决办法
    Scalaz(35)- Free :运算-Trampoline,say NO to StackOverflowError
    Scalaz(34)- Free :算法-Interpretation
    Scalaz(33)- Free :算式-Monadic Programming
    Scalaz(32)- Free :lift
    Scalaz(31)- Free :自由数据结构-算式和算法的关注分离
    Scalaz(30)- Free :Natural Tranformation ~>
  • 原文地址:https://www.cnblogs.com/bigben0123/p/13728595.html
Copyright © 2011-2022 走看看