c++字符编码转换
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++字符编码转换的更多相关文章
- iconv字符编码转换
转自 http://blog.csdn.net/langresser_king/article/details/7459367 iconv(http://www.gnu.org/software/li ...
- Char Tools,方便的字符编码转换小工具
工作关系,常有字符编码转换方面的需要,写了这个小工具 Char Tools是一款方便的字符编码转换小工具,基于.Net Framework 2.0 Winform开发 主要功能 URL编码:URLEn ...
- php 字符编码转换函数 iconv mb_convert_encoding比较
在使用PHP处理字符串时,我们经常会碰到字符编码转换的问题,你碰到过iconv转换失败吗? 发现问题时,网上搜了搜,才发现iconv原来有bug ,碰到一些生僻字就会无法转换,当然了配置第二个参数时, ...
- 编码问题 php字符编码转换类
各种平台和软件打开显示的编码问题,需要使用不同的编码,根据我们不同的需求. php 字符编码转换类,支持ANSI.Unicode.Unicode big endian.UTF-8.UTF-8+Bom ...
- Python—字符编码转换、函数基本操作
字符编码转换 函数 #声明文件编码,格式如下: #-*- coding:utf-8 -*- 注意此处只是声明了文件编码格式,python的默认编码还是unicode 字符编码转换: import sy ...
- php字符编码转换之gb2312转为utf8(转)
在php中字符编码转换我们一般会用到iconv与mb_convert_encoding进行操作,但是mb_convert_encoding在转换性能上比iconv要差很多哦.string iconv ...
- day4学python 字符编码转换+元组概念
字符编码转换+元组概念 字符编码转换 #coding:gbk //此处必声明 文件编码(看右下角编码格式) #用来得到python默认编码 import sys print(sys.getdefaul ...
- erlang中字符编码转换(转)
转自:http://www.thinksaas.cn/group/topic/244329/ 功能说明: erlang中对各种语言的编码支持不足,此代码是使用erlang驱动了著名的iconv编码库来 ...
- Qt代码区字符编码转换
在做通讯练习的时候,发现发送给小助手字符乱码,图片如下 本人Qt Creator是UTF-8,需要改成gbk,代码如下 #include<QTextCodec> // 提供字符编码转换 Q ...
- C++ 字符编码转换类
记录一下C++ 编码转换的函数: #pragma once #include "afx.h" #define DEFAULT_CODE 0 #define CHINESE_SIMP ...
随机推荐
- ubuntu 使用natapp配置内网穿透
前言 在自己的服务器上起了服务,但由于域名还没申请下来,无法使用域名测试微信公众号接口,辛亏看到了这个博客:Natapp内网穿透服务工具.跟随这篇博客,我搭建了自己的内网穿透服务,现在记录如下. 过程 ...
- 2024已过半,还没试过在vue3中使用ioc容器吗?
Vue3 已经非常强大和灵活了,为什么还要引入 IOC 容器呢?IOC 容器离不开 Class,那么我们就从 Class 谈起 Class的应用场景 一提起 Class,大家一定会想到这是 Vue 官 ...
- SpringBoot2.X新版本配置拦截器在项目中的使用
拦截器:和过滤器用途基本类似 SpringBoot2.X新版本配置拦截器 implements WebMvcConfigure 自定义拦截器 HandlerInterceptor preHandle: ...
- SpringBoot中使用Servlet3.0注解开发自定义的拦截器
使用Servlet3.0的注解进行配置步骤 启动类里面加@ServletComponentScan,进行扫描 新建一个Filter类,implements Filter,并实现对应的接口 @WebFi ...
- 洛谷P1790
这道题可以说也是非常有意思的数学题,并且坑点也是非常多 刚开始以为是连通块的问题,后面发现没有那么简单,因为必须要分成两个部分才行,连通块可能会分成三个部分 后面想到利用割痕来解决,以为唯一的一种分割 ...
- 使用ML.NET训练一个属于自己的图像分类模型,对图像进行分类就这么简单!
前言 今天大姚给大家分享一个.NET开源.免费.跨平台(支持Windows.Linux.macOS多个操作系统)的机器学习框架:ML.NET.并且本文将会带你快速使用ML.NET训练一个属于自己的图像 ...
- 可视化—D3学习笔记小小案例记录一下
D3全称是Data-Driven Documents数据驱动文档,是一个开源的javascript库,可以用于数据可视化图形的创建,该库更接近底层,与 g2.echarts 不同,d3 能直接操作 s ...
- C#:利用“事务+乐观锁+version”解决并发下的数据一致性问题
本文重点介绍通过事务控制,利用数据库的乐观锁和时间戳,来解决并发(非高并发)环境下的脏读.幻读.不可重复读等问题,同时也能解决超卖等现象,对开发企业管理系统的朋友提供一个思路,为更突出主题思路,文涉及 ...
- for循环以及常用的遍历(迭代)用法
for循环以及常用的遍历(迭代)用法 概念:(概念才是高楼的地基!) for循环是一个计次循环,一般运用在循环次数已知的情况下.通常适用于枚举或遍历序列,以及迭代序列中的元素. 注意*:迭代变量用 ...
- 从pytest源码的角度分析pytest工作原理
从pytest源码的角度分析pytest工作原理 从 pytest 源代码的角度来分析其工作原理,我们需要关注几个关键的部分,特别是 pytest 的启动过程以及测试的收集与执行.下面是基于 pyte ...