std::string std::wstring char w_char 内部中文编码
最近在处理一个字符串转码问题,故记录一下过程
该需求是外部 sdk 的一个 api 需要一个 char* 字符串路径入参,我以往是将宽字符串转为 UTF8 后再传给 sdk
这次这个 api 似乎不接受 UTF8 编码的字符串路径,于是我改用系统编码传参作测试,也就是将 GB2312 编码的字符串路径传给它
结果显示该 api 只接受本地编码的字符串路径,因此我要处理宽字符串转为系统编码的问题
我在 stackoverflow 论坛上搜到一些答案
其中有一个方法要注意避坑,

这是个高赞答案,链接:https://stackoverflow.com/a/12097772/11128312
但是这个只适用于英文字符,因为这种转换相当于把宽字节的第二个字节抹除了,比如,
“帮助” 的 unicode 编码为:2e 5e a9 52
使用上图的方法就给你干掉宽字节的第二个字节,
变成:2e a9
这是一个四不像字符
英文字符就不一样了,比如
“he” 的 unicode 编码为:68 00 65 00
用 std::string 就可以去掉 00,
变成:68 65
故我们要用其他方法来转换,方法很多,我这里列举两个,
C++17 后支持 std::filesystem::path 直接转,示例,
#include <filesystem> const std::wstring wPath = GetPath(); // some function that returns wstring
const std::string path = std::filesystem::path(wPath).string();
也可以使用 WcToMb 工具函数
WcToMb 原型:
char* WcToMb(const wchar_t *str)
{
char *mbstr = NULL;
lo_W2C(&mbstr, str);
return mbstr;
}
lo_W2C 内部也是用的 WideCharToMultiByte 函数转换的
lo_W2C 函数原型
/*
** Convert microsoft unicode to multibyte character string, based on the
** user's Ansi codepage.
**
** Space to hold the returned string is obtained from
** malloc().
*/
int lo_W2C(char** pout ,const wchar_t *zWide)
{
#if (defined(WIN32) || defined(_WIN32) )
char *zname = 0;
int codepage = 0;
int nByte = 0; if( !zWide || *zWide == '\0' )
return 0; #if defined(_WIN32_WCE)
codepage = CP_ACP ;
#else
codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
#endif
nByte = WideCharToMultiByte(codepage, 0, zWide, -1, 0, 0, 0, 0);
zname = (char*)malloc( nByte + 1 );
if( zname == 0 ) return 0; nByte = WideCharToMultiByte(codepage, 0, zWide, -1, zname, nByte+1, 0, 0);
if( nByte > 0 ) zname[nByte] = '\0'; *pout = zname;
return nByte;
#else const wchar_t* in = zWide;
size_t in_len = wcslen(in);
size_t outlen = bbiconv_counts_wchar_2_gbk(in , in_len);
if( outlen <= 0 )
return -1; char* out_ptr = (char*)malloc( (sizeof(char)) * (outlen+1) );
if( !out_ptr )
return -1; bbiconv_wchar_2_gbk(in , in_len , out_ptr , outlen);
*pout = out_ptr;
return outlen; #endif //#if (defined(WIN32) || defined(_WIN32) ) }
补充:
std::wstring 和 wchar_t 内部中文编码是按照 unicode 编码的
std::string 和 char 内部中文编码是按照系统字符集编码,一般中文是 GB2312 字符集
另附:
std::string std::wstring char w_char 内部中文编码的更多相关文章
- std::string stringf(const char* format, ...)
std::string stringf(const char* format, ...){ va_list arg_list; va_start(arg_list, format); // SUSv2 ...
- How to convert a std::string to const char* or char*?
How to convert a std::string to const char* or char*? 1. If you just want to pass a std::string to a ...
- std::string, std::wstring, wchar_t*, Platform::String^ 之间的相互转换
最近做WinRT的项目,涉及到Platform::String^ 和 std::string之间的转换,总结一下: (1)先给出源代码: std::wstring stows(std::string ...
- 为什么推荐std::string而不是char*
例如如下: map<const char*, const char*> map_test; map_test["a"] = "a"; map_tes ...
- std::string std::wstring 删除最后元素 得到最后元素
std::string str = "abcdefg,"; std::cout << "last character:"<<str.ba ...
- std::string,std::vector,std::accumulate注意事项
在用string做字符串拼接时,会发现随着string的增大越来越慢,原因主要是string(和vector)是基于现行内存的数据结构,在海量数据时,经常会申请新的一块内存,把原有的数据拷贝过去然后再 ...
- C++ MFC std::string转为 std::wstring
std::string转为 std::wstring std::wstring UTF8_To_UTF16(const std::string& source) { unsigned long ...
- 对std::string和std::wstring区别的解释,807个赞同,有例子
807down vote string? wstring? std::string is a basic_string templated on a char, and std::wstring on ...
- C++ std::unordered_map使用std::string和char *作key对比
最近在给自己的服务器框架加上统计信息,其中一项就是统计创建的对象数,以及当前还存在的对象数,那么自然以对象名字作key.但写着写着,忽然纠结是用std::string还是const char *作ke ...
- QString, Std::string, char *相互转换
Qt 库中对字符串类型进行了封装,QString 类提供了所有字符串操作方法,给开发带来了便利. 由于第三方库的类型基本上都是标准的类型,即使用std::string或char *来表示字符 (串) ...
随机推荐
- [转帖]修改jmeter内存配置(win&mac&linux)
目录 一.背景: 二.win环境下修改jmeter内存 三.mac&linux环境下修改jmeter内存 四.验证内存是否修改成功 一.背景: 在进行大数据.高并发压测的过程性,有时会遇上JM ...
- 【转帖】再谈TCP/IP三步握手&四步挥手原理及衍生问题—长文解剖IP
https://www.zhoulujun.cn/html/theory/ComputerScienceTechnology/network/2015_0708_65.html 长文是对TCP IP的 ...
- [转帖]docker build 中的 -f 选项
https://www.jianshu.com/p/06c35fd299b7 需要注意的是,在 docker build 命令接收的参数中,提供给 docker build 命令的 -f 选项应该 D ...
- [转帖][问题已处理]-kubernetes中2次不同的oom处理
https://dandelioncloud.cn/article/details/1598699030236577793 起因: 同事反馈 服务挂了,kuboard上查看是服务挂掉了,livenes ...
- Docker 23.0.0 简单学习与使用
前言 Docker 从2013年火起来到现在才第十个年头. 现在已经被Google的K8S打的没有任何还手之力. 随着K8S放弃支持docker,仅支持containerd的方式. 直接导致docke ...
- nginx 进行目录浏览的简单配置
1. 公司网络安全不让用vsftpd的匿名网络访问了, 没办法 只能够使用 nginx 通过http协议来处理. 2. 最简单的办法就是另外开一个nginx进程简单设置一下nginx的配置文件 wor ...
- 龙芯中标麒麟 上面安装libgdiplus的方法
其实方法与之前的blog 基本上完全一样 但是发现有一个问题 安装完libgdiplus之后必须重启一下才能有效果... CentOS 安装libgdi的方法 1. 安装必须的包 1 yum ins ...
- 境内下载nodejs二进制文件
下载 nodejs 安装包的方法 找到一个境内的淘宝源 可以直接使用 下载速度还比较快 但是没有 龙芯的.. http://npm.taobao.org/mirrors/node/v10.20.0/
- CDP技术系列(三):百万级QPS的人群命中服务接口性能优化指南
一.背景介绍 CDP系统提供了强大的标签和群体的构建能力,面对海量数据的标签和群体,我们采用了Bitmap+ClickHouse的存储与计算方案.详细内容可以参考之前文章. 有了群体之后,它们被广泛的 ...
- 通过Environment获取属性文件的值,竟然会调用到JNDI服务!!!
一.背景介绍 某应用在压测过程机器cpu使用率超过80%,通过在线诊断工具进行CPU采样生成的火焰图,看到程序中频繁调用environment.getProperty()获取属性值,而其内部调用了Jn ...