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 *来表示字符 (串) ...
随机推荐
- Cloudquery的学习安装与使用
Cloudquery的学习安装与使用 下载 官方下载地址: https://www.cloudquery.club/download https://pan.baidu.com/s/1a7XOrnMU ...
- [转帖]create table INITRANS参数分析
https://www.modb.pro/db/44701 1. 内容介绍 Oracle数据库create table时使用INITRANS参数设置数据块ITL事务槽的数量,确保该数据块上 并发事务数 ...
- [转帖]PostgreSQL 统计所有数据表各自的总行数
一般来说,可以使用 count(*) 来获取具体某张表的总行数: SELECT count(0) FROM t_user; 如果想获得所有表的行数信息,可以使用以下 SQL 语句: SELECT re ...
- [转帖]centos7离线安装postgresql13
https://www.cnblogs.com/summer-88/p/15341918.html 在一台可以联网的centos上安装postgresql源 yum install -y https: ...
- JVM内存学习 2.0
先说一下结果 1. Linux的内存分配是惰性分配的. APP申明了 kernel并不会立即进行初始化和使用. 2. JVM的内存主要分为, 堆区, 非堆区, 以及jvm使用的其他内存. 比如直接内存 ...
- Redis monitor命令
MONITOR Syntax MONITOR Available since: 1.0.0 Time complexity: ACL categories: @admin, @slow, @dange ...
- OpenPower机器上面搭建RabbitMQ 以及简单进行用户配置的方法
OpenPower机器上面搭建RabbitMQ 以及简单进行用户配置的方法 公司有一台性能比较好的power机器. 同事要求安装rabbitmq 今天尝试进行了一下处理 公司里面有网络有相应的源 性能 ...
- vue3封装搜索表单组件
seacrch 表单完成的功能 1.根据配置json配置项自动生成表单 ok 2.是响应式的排版 ok 3.点击搜索按钮会向上抛出值 ok 4.点击重置按钮会自动清空数据,不需要父组件额外的处理 ok ...
- Windows 10 关闭搜索栏中“热门搜索”的显示。
Windows 10 关闭搜索栏中"热门搜索"的显示. 任务栏取消"显示搜索突出显示"的设置可能无法取消"热门搜索"的显示, 这就需要您尝试 ...
- #region在多种编程语言及IDE中进行代码折叠,包括python msvc++ c#等
vs/rider中折叠C#代码 在写C#的时候,在visual studio中可以使用#region和#endregion来进行代码折叠,那么在pycharm中是否可以呢? //这里有很多的代码... ...