c++11支持 utf-8了,还有一套字符转换函数。但是我越来越晕了。

飞翔的薄荷 2015-05-22 04:33:28
.

c++11 好像用u8来表示utf-8,然后还有一大套转换函数 u16string,char16_t。std::codecvt_utf8 std::codecvt_utf16 std::codecvt_utf8_utf16 wstring_convert。
谁能说下这些函数这么用,它们之间的关系是啥子。

然后还有utf-8如何转换为gb2313,像下面这样结果是乱码。
std::string str2 = u8"你好啊";
std::cout << str2 << std::endl;


.
...全文
5204 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
你咋这么皮 2018-12-01
  • 打赏
  • 举报
回复
引用 3 楼 飞翔的薄荷 的回复:
gb2312和utf8相互转换:

std::string gb2312_to_utf8(std::string const &strGb2312)
{
std::vector<wchar_t> buff(strGb2312.size());
#ifdef _MSC_VER
std::locale loc("zh-CN");
#else
std::locale loc("zh_CN.GB18030");
#endif
wchar_t* pwszNext = nullptr;
const char* pszNext = nullptr;
mbstate_t state = {};
int res = std::use_facet<std::codecvt<wchar_t, char, mbstate_t> >
(loc).in(state,
strGb2312.data(), strGb2312.data() + strGb2312.size(), pszNext,
buff.data(), buff.data() + buff.size(), pwszNext);

if (std::codecvt_base::ok == res)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> cutf8;
return cutf8.to_bytes(std::wstring(buff.data(), pwszNext));
}

return "";

}

std::string utf8_to_gb2312(std::string const &strUtf8)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> cutf8;
std::wstring wTemp = cutf8.from_bytes(strUtf8);
#ifdef _MSC_VER
std::locale loc("zh-CN");
#else
std::locale loc("zh_CN.GB18030");
#endif
const wchar_t* pwszNext = nullptr;
char* pszNext = nullptr;
mbstate_t state = {};

std::vector<char> buff(wTemp.size() * 2);
int res = std::use_facet<std::codecvt<wchar_t, char, mbstate_t> >
(loc).out(state,
wTemp.data(), wTemp.data() + wTemp.size(), pwszNext,
buff.data(), buff.data() + buff.size(), pszNext);

if (std::codecvt_base::ok == res)
{
return std::string(buff.data(), pszNext);
}
return "";
}

注意linux要支持zh_CN.GB18030代码才能正常运行。Ubuntu下使用cat /var/lib/locales/supported.d/local 来查看系统是否支持zh_CN.GB18030。

太感谢您了,用了您提供的代码我成功解决了问题,找资料都快找疯了,自学小白不容易啊
你咋这么皮 2018-12-01
  • 打赏
  • 举报
回复
引用 2 楼 赵4老师 的回复:
// UTF-8 编码字符理论上可以最多到 6个字节长,但目前全世界的所
// 有文字和符号种类加起来也只要编到 4个字节长就够了。
//   UTF-8 是以 8位(即 1个字节)为单元对原始码进行编码(注意一
// 点:这里所讲的原始码都是指Unicode码),并规定:多字节码(2个字
// 节以上才称为多字节)以转换后第1个字节起头的连续“1”的数目(这
// 些连续“1”称为标记位),表示转换成几个字节:“110”连续两个
// “1”,表示转换结果为2个字节,“1110”表示3个字节,而“11110”
// 则表示4个字节……跟随在标记位之后的“0”,其作用是分隔标记位和
// 字符码位。第2~第4个字节的起头两个位固定设置为“10”,也作为标
// 记,剩下的6个位才做为字符码位使用。
//   这样,2字节UTF-8码剩下11个字符码位,可用以转换0080~07FF的
// 原始字符码,3字节剩下16个字符码位,可用以转换0800~FFFF的原始字
// 符码,由此类推。编码方式的模板如下:
//
// 原始码(16进制) UTF-8编码(二进制)
// --------------------------------------------
// 0000 - 007F 0xxxxxxx
// 0080 - 07FF 110xxxxx 10xxxxxx
// 0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx
// ……
// --------------------------------------------
//
//   模板中的“x”表示字符码。
//   Ascii码<007F,编为1个
// 字节的UTF-8码。汉字的 Unicode编码范围为0800-FFFF,所以被编为
// 3个字节的UTF-8码。
//   例如“汉”字的Unicode编码是6C49,6C49在0800-FFFF之间,所以
// 要用3个字节的模板:1110wwww 10xxxxyy 10yyzzzz。

// 6 C 4 9
// 0110 1100 0100 1001
// wwww xxxx yyyy zzzz
// wwww xxxxyy yyzzzz
// 1110wwww 10xxxxyy 10yyzzzz。
// 11100110 10110001 10001001
// E 6 B 1 8 9
//“汉”字的UTF-8编码是E6 B1 89

老师能帮我修改几行代码吗,我实在没弄懂Unicode转UTF-8
你咋这么皮 2018-11-30
  • 打赏
  • 举报
回复
小白辛辛苦苦自学C++,目前卡在编码这里了。都快要死了

使用xlnt库生成excel的时候,如果在代码中定义了中文字符串的,在写入到workbook对象中都没有问题,但是一旦使用xlnt库内置方法save(“文件名”)保存为新的excel文件的时候就会出现异常: xml::serialization。全英文或者数字则不会出现这种现象,同理从excel文件中读取中文然后输出到cmd的时候,也会显示乱码,有没有高手能帮帮我这个小白解决啊,感激不尽。程序字符集是使用的unicode,我知道要将代码中的string转换,但是我不懂怎么转啊,求大神帮助啊。。
飞翔的薄荷 2017-06-14
  • 打赏
  • 举报
回复
引用 3 楼 ml232528 的回复:
gb2312和utf8相互转换:
头文件 #include <codecvt> #include <locale>
飞翔的薄荷 2015-07-31
  • 打赏
  • 举报
回复
gb2312和utf8相互转换: std::string gb2312_to_utf8(std::string const &strGb2312) { std::vector<wchar_t> buff(strGb2312.size()); #ifdef _MSC_VER std::locale loc("zh-CN"); #else std::locale loc("zh_CN.GB18030"); #endif wchar_t* pwszNext = nullptr; const char* pszNext = nullptr; mbstate_t state = {}; int res = std::use_facet<std::codecvt<wchar_t, char, mbstate_t> > (loc).in(state, strGb2312.data(), strGb2312.data() + strGb2312.size(), pszNext, buff.data(), buff.data() + buff.size(), pwszNext); if (std::codecvt_base::ok == res) { std::wstring_convert<std::codecvt_utf8<wchar_t>> cutf8; return cutf8.to_bytes(std::wstring(buff.data(), pwszNext)); } return ""; } std::string utf8_to_gb2312(std::string const &strUtf8) { std::wstring_convert<std::codecvt_utf8<wchar_t>> cutf8; std::wstring wTemp = cutf8.from_bytes(strUtf8); #ifdef _MSC_VER std::locale loc("zh-CN"); #else std::locale loc("zh_CN.GB18030"); #endif const wchar_t* pwszNext = nullptr; char* pszNext = nullptr; mbstate_t state = {}; std::vector<char> buff(wTemp.size() * 2); int res = std::use_facet<std::codecvt<wchar_t, char, mbstate_t> > (loc).out(state, wTemp.data(), wTemp.data() + wTemp.size(), pwszNext, buff.data(), buff.data() + buff.size(), pszNext); if (std::codecvt_base::ok == res) { return std::string(buff.data(), pszNext); } return ""; } 注意linux要支持zh_CN.GB18030代码才能正常运行。Ubuntu下使用cat /var/lib/locales/supported.d/local 来查看系统是否支持zh_CN.GB18030。
赵4老师 2015-05-22
  • 打赏
  • 举报
回复
// UTF-8 编码字符理论上可以最多到 6个字节长,但目前全世界的所
// 有文字和符号种类加起来也只要编到 4个字节长就够了。
//   UTF-8 是以 8位(即 1个字节)为单元对原始码进行编码(注意一
// 点:这里所讲的原始码都是指Unicode码),并规定:多字节码(2个字
// 节以上才称为多字节)以转换后第1个字节起头的连续“1”的数目(这
// 些连续“1”称为标记位),表示转换成几个字节:“110”连续两个
// “1”,表示转换结果为2个字节,“1110”表示3个字节,而“11110”
// 则表示4个字节……跟随在标记位之后的“0”,其作用是分隔标记位和
// 字符码位。第2~第4个字节的起头两个位固定设置为“10”,也作为标
// 记,剩下的6个位才做为字符码位使用。
//   这样,2字节UTF-8码剩下11个字符码位,可用以转换0080~07FF的
// 原始字符码,3字节剩下16个字符码位,可用以转换0800~FFFF的原始字
// 符码,由此类推。编码方式的模板如下:
//
// 原始码(16进制) UTF-8编码(二进制)
// --------------------------------------------
// 0000 - 007F       0xxxxxxx
// 0080 - 07FF       110xxxxx 10xxxxxx
// 0800 - FFFF       1110xxxx 10xxxxxx 10xxxxxx
// ……
// --------------------------------------------
//
//   模板中的“x”表示字符码。
//   Ascii码<007F,编为1个
// 字节的UTF-8码。汉字的 Unicode编码范围为0800-FFFF,所以被编为
// 3个字节的UTF-8码。
//   例如“汉”字的Unicode编码是6C49,6C49在0800-FFFF之间,所以
// 要用3个字节的模板:1110wwww 10xxxxyy 10yyzzzz。

//    6    C    4    9
// 0110 1100 0100 1001
// wwww xxxx yyyy zzzz
//     wwww   xxxxyy   yyzzzz
// 1110wwww 10xxxxyy 10yyzzzz。
// 11100110 10110001 10001001
//    E   6    B   1    8   9
//“汉”字的UTF-8编码是E6 B1 89
flyrack 2015-05-22
  • 打赏
  • 举报
回复
U8 U16都是U码 GB2313 不是U码 是大陆专用码 所以标准库永远都不会支持的

65,085

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧