c++字符编码转换

简述

字符编码一直是软件开发中很麻烦的问题。当前项目开发普遍使用的字符集是utf-8,而windows系统则默认是gbk,linux默认编码则是utf-8,所以想要开发一个在windows正常运行的软件,就需要考虑字符集的问题。

c++11新增了很多本地化的功能,包括字符编码转换等,主要使用wstring_convert和codecvt相结合进行转换,下面介绍具体的方法供大家学习(复制粘贴 )。

windows:gbk编码,std::wstring = std::u16string,wchar_t = char16_t (utf-16编码)

linux:utf-8编码,std::wstring = std::u32string,wchar_t = char32_t (utf-32编码)

编码转换

  • 依赖的头文件:

    #include <codecvt>
    #include <locale>
  • 转换方法:

    coding.h

    #ifndef TE_TEST_CODING_H
    #define TE_TEST_CODING_H #include <string> namespace coding { #ifdef _WIN32
    //GBK locale name in windows
    inline constexpr const char * GBK_LOCALE_NAME = ".936";
    #else
    inline constexpr const char * GBK_LOCALE_NAME = "zh_CN.GBK";
    #endif /**
    * utf-8 --> wchar
    * @param _utf8 要求std::string的编码是utf-8
    * @return 宽字符串
    */
    std::wstring utf8_to_wstr(const std::string& _utf8); /**
    * wchar --> utf-8
    * @param _wstr 宽字符串
    * @return 转化为utf-8 编码的字符串
    */
    std::string wstr_to_utf8(const std::wstring& _wstr); /**
    * utf-8 --> gbk
    * @param _utf8 utf-8
    * @return gbk
    */
    std::string utf8_to_gbk(const std::string& _utf8); /**
    * gbk --> utf-8
    * @param _gbk gbk
    * @return utf-8
    */
    std::string gbk_to_utf8(const std::string& _gbk); /**
    * gbk --> std::wstring
    * @param _gbk gbk
    * @return 宽字符串
    */
    std::wstring gbk_to_wstr(const std::string& _gbk); /**
    * std::wstring --> gbk
    * @param _wstr 宽字符串
    * @return gbk
    */
    std::string wstr_to_gbk(const std::wstring& _wstr);
    } #endif //TE_TEST_CODING_H

    coding.cpp

    #include "coding.h"
    
    #include <codecvt>
    #include <locale> // 包装 wstring/wbuffer_convert 所用的绑定本地环境平面的工具
    template<class Facet>
    struct deletable_facet : Facet
    {
    template<class ...Args>
    explicit deletable_facet(Args&& ...args) : Facet(std::forward<Args>(args)...) {}
    ~deletable_facet() override = default;
    }; std::wstring coding::utf8_to_wstr(const std::string &_utf8) {
    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    return converter.from_bytes(_utf8);
    } std::string coding::wstr_to_utf8(const std::wstring &_wstr) {
    std::wstring_convert<std::codecvt_utf8<wchar_t>> convert;
    return convert.to_bytes(_wstr);
    } std::string coding::utf8_to_gbk(const std::string &_utf8) {
    std::wstring tmp_wstr = utf8_to_wstr(_utf8);
    return wstr_to_gbk(tmp_wstr);
    } std::string coding::gbk_to_utf8(const std::string &_gbk) {
    std::wstring tmp_wstr = gbk_to_wstr(_gbk);
    return wstr_to_utf8(tmp_wstr);
    } std::wstring coding::gbk_to_wstr(const std::string &_gbk) {
    using codecvt = deletable_facet<std::codecvt_byname<wchar_t, char, mbstate_t>>;
    std::wstring_convert<codecvt> convert(new codecvt(GBK_LOCALE_NAME));
    return convert.from_bytes(_gbk);
    } std::string coding::wstr_to_gbk(const std::wstring& _wstr) {
    using codecvt = deletable_facet<std::codecvt_byname<wchar_t, char, mbstate_t>>;
    std::wstring_convert<codecvt> convert(new codecvt(GBK_LOCALE_NAME));
    return convert.to_bytes(_wstr);
    }

补充说明

结构体deletable_facet的作用是公有化codecvt_byname模板类的析构函数,该类的析构函数默认为 protected。部分编译环境实现允许析构析构方法为保护的对象,但部分(如GUN)要求自定义类,继承 Facet 并有 public 的析构方法,否则会出现以下问题:

In file included from /usr/include/c++/6.2.1/bits/locale_conv.h:41:0,
from /usr/include/c++/6.2.1/locale:43,
from main.cpp:3: /usr/include/c++/6.2.1/bits/unique_ptr.h: In instantiation of ‘void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = std::codecvt<wchar_t, char, __mbstate_t>]’:
/usr/include/c++/6.2.1/bits/unique_ptr.h:236:17: required from ‘std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = std::codecvt<wchar_t, char, __mbstate_t>; _Dp = std::default_delete<std::codecvt<wchar_t, char, __mbstate_t> >]’
/usr/include/c++/6.2.1/bits/locale_conv.h:218:7: required from here
/usr/include/c++/6.2.1/bits/unique_ptr.h:76:2: error: ‘virtual std::codecvt<wchar_t, char, __mbstate_t>::~codecvt()’ is protected within this context
delete __ptr;
^~~~~~
In file included from /usr/include/c++/6.2.1/codecvt:41:0,
from main.cpp:1:
/usr/include/c++/6.2.1/bits/codecvt.h:426:7: note: declared protected here
~codecvt();
^

详情可见官方文档说明

本文参考了博客并在其基础上进行补充完善,修复了部分问题。

c++字符编码转换的更多相关文章

  1. iconv字符编码转换

    转自 http://blog.csdn.net/langresser_king/article/details/7459367 iconv(http://www.gnu.org/software/li ...

  2. Char Tools,方便的字符编码转换小工具

    工作关系,常有字符编码转换方面的需要,写了这个小工具 Char Tools是一款方便的字符编码转换小工具,基于.Net Framework 2.0 Winform开发 主要功能 URL编码:URLEn ...

  3. php 字符编码转换函数 iconv mb_convert_encoding比较

    在使用PHP处理字符串时,我们经常会碰到字符编码转换的问题,你碰到过iconv转换失败吗? 发现问题时,网上搜了搜,才发现iconv原来有bug ,碰到一些生僻字就会无法转换,当然了配置第二个参数时, ...

  4. 编码问题 php字符编码转换类

    各种平台和软件打开显示的编码问题,需要使用不同的编码,根据我们不同的需求. php 字符编码转换类,支持ANSI.Unicode.Unicode big endian.UTF-8.UTF-8+Bom ...

  5. Python—字符编码转换、函数基本操作

    字符编码转换 函数 #声明文件编码,格式如下: #-*- coding:utf-8 -*- 注意此处只是声明了文件编码格式,python的默认编码还是unicode 字符编码转换: import sy ...

  6. php字符编码转换之gb2312转为utf8(转)

    在php中字符编码转换我们一般会用到iconv与mb_convert_encoding进行操作,但是mb_convert_encoding在转换性能上比iconv要差很多哦.string iconv ...

  7. day4学python 字符编码转换+元组概念

    字符编码转换+元组概念 字符编码转换 #coding:gbk //此处必声明 文件编码(看右下角编码格式) #用来得到python默认编码 import sys print(sys.getdefaul ...

  8. erlang中字符编码转换(转)

    转自:http://www.thinksaas.cn/group/topic/244329/ 功能说明: erlang中对各种语言的编码支持不足,此代码是使用erlang驱动了著名的iconv编码库来 ...

  9. Qt代码区字符编码转换

    在做通讯练习的时候,发现发送给小助手字符乱码,图片如下 本人Qt Creator是UTF-8,需要改成gbk,代码如下 #include<QTextCodec> // 提供字符编码转换 Q ...

  10. C++ 字符编码转换类

    记录一下C++ 编码转换的函数: #pragma once #include "afx.h" #define DEFAULT_CODE 0 #define CHINESE_SIMP ...

随机推荐

  1. tensorflow学习率指数衰减ExponentialDecay的参数介绍与使用方法

      本文介绍在tensorflow库中,用于动态调整神经网络的学习率的一种方法--指数衰减ExponentialDecay()策略的参数含义及其具体用法.   在进行神经网络训练时,我们经常需要用到动 ...

  2. [oeasy]python0125_汉字打印机_点阵式打字机_汉字字形码

    汉字字形码 回忆上次内容 IBM 将 ASCII 扩展之后 规定了 一个字节的字符集 并制作了 相应的字形库   ​   添加图片注释,不超过 140 字(可选)   这种显示模式和字符大小之下 中文 ...

  3. 【译】使 Visual Studio 更加可视化

    任何 Web.桌面或移动开发人员都经常使用图像.你可以从 C#.HTML.XAML.CSS.C++.VB.TypeScript 甚至代码注释中引用它们.有些图像是本地的,有些存在于线上或网络共享中,而 ...

  4. python 列表append和 的区别??

    python列表中的合并 python列表中append方法是给列表增加一个元素,而'+='是增加上该符号后边的元素,类似于extend方法 不知道对错,先记下来.我学的append方法是在列表最后追 ...

  5. vue小知识:多层数据双向相应之向上派发和向下派发($dispatch和$broadcast)

    注意:这两个实例已经在vue3中弃用啦!!!(所以不详细说了,封装知道怎么用就行了,作为了解) 都是在vue实例配置(main.js) 向上派发:$dispatch 注意,在相应后代组件中使用 thi ...

  6. Python 结合opencv实现图片截取和拼接

    实践环境 python 3.6.2 scikit-build-0.16.7 win10 opencv_python-4.5.4.60-cp36-cp36m-win_amd64.whl 下载地址: ht ...

  7. scratch源码下载 | 蜘蛛传说

    程序说明: <蜘蛛传说>是一个通过Scratch平台制作的互动游戏项目.在这个故事中,玩家将扮演一只蜘蛛,其原本和平的生活被一只入侵的壁虎所打破.为了保卫自己的家园,蜘蛛必须运用智慧和勇气 ...

  8. Jmeter函数助手2-Random

    Random函数用于获取随机范围内的正整数或负整数. 一个范围内的最小值:必填,且必须填入整数(正负数都可以) 一个范围内允许的最大值:必填,且必须填入整数(正负数都可以).最大值需大于最小值如[-6 ...

  9. Python将信息发送到指定邮箱

    目的:将Python执行脚本结果发送到指定邮箱 使用场景:可将每天.每周定时任务python跑的结果汇总,定时发送到小组成员/领导邮箱中 1.以下163邮箱为例,设置发件人是163邮箱,接收人是qq邮 ...

  10. 【Layui】03 按钮 Button

    文档位置: https://www.layui.com/doc/element/button.html 01.[按钮主题] <div> <button type="butt ...