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 *来表示字符 (串) ...
随机推荐
- ingress nginx 支持的K8S版本以及nginx版本信息
- [转帖]Region 性能调优
https://docs.pingcap.com/zh/tidb/v6.5/tune-region-performance 本文介绍了如何通过调整 Region 大小等方法对 Region 进行性能调 ...
- 【转帖】读懂什么是RDMA
一.什么是RDMA1.RDMA主要体现 2.如何理解RDMA和TCP技术的区别?3.使用RDMA的好处包括: 二.什么是RoCE?1. RDMA协议包含:Infiniband(IB)2. 为什 ...
- [转帖]AnolisOS8安装ntp同步时间
https://www.wlnmp.com/post-673.html 在AnolisOS8中默认不再支持ntp软件包,时间同步将由chrony来实现,如果你习惯了使用ntp来同步时间,一时难以去适应 ...
- CentOS确认网口是否插入网线的办法
最近公司的机器存在网络问题, 部分网络总是不通, 比较奇怪. 最近一直想处理好. 第一步: 先查看网口的设备信息 可以使用 ip link show 可以讲网口信息都展示出来. 一般情况下 NO-C ...
- vue3中retive的错误用法导致数据不跟新
retive的错误用法 <template> <div> 司藤的信息==>{{ objInfo }} <button @click="handerHttp ...
- Ant Design Vue中TreeSelect详解
<template> <a-tree-select v-model:value="value" style="width: 320px" :t ...
- 正则表达式match方法和search方法
正则表达式, //match() 方法可在字符串内检索指定的值 找到返回相关数据,找不到返回null var part = /Box/ig; var str = "this is box,i ...
- cookie的设置读取
<script> // 设置cookie值哈 let username = '我是cookie' document.cookie = "name=" + usernam ...
- vim 从嫌弃到依赖(7)——可视模式
vim 的可视模式下可以选择一个区域,然后针对区域进行操作.可视模式有点类似于在其他编辑器上使用鼠标选中一块区域然后针对区域进行操作. vim中有3种可视模式,分别用来处理不同范围的文本: 处理字符的 ...