c++ - 有什么办法可以在 utf-8 和平台无关的纯字符串之间进行转换吗?

标签 c++ c++11 encoding utf-8 gb2312

这里的纯字符串有一种编码:

  • 普通字符串文字,例如 "plainstring" 编码为;

  • 所有标准库都返回或接受。例如:


std::cout << "I'm ok." ; // plain string, ok on my system,
                            // VS2015 x64 default encoding setting.
std::cout << u8"I'm wrong."; // got error display on my system

std::experimental::filesystem::path path("Some Right specified Path contains non-ASCII chars"); // ok

std::experimental::filesystem::path path2(u8"Some Path specified Path contains non-ASCII chars"); // error

std::experimental::filesystem::directory_iterator r(path); // ok

std::experimental::filesystem::directory_iterator r2(path2); // will throw exception

据我所知,我的系统 (windows 10 x64) 对这种纯字符串使用 GB2312 编码。

但是如何以独立于平台的方式将它们转换为(并转换回)其他编码,例如 utf-8??

最佳答案

这是一个看似简单的问题,其实是一个极其复杂的问题。

简短的回答:从 GB2312 到 UTF-8 然后返回到 GB2312 的往返是可能的,但是你不能从 UTF-8 到 GB2312 然后返回到 UTF-8 的往返转换。

较长的答案:任何可以用符合标准的方式表示的字符串都可以用 Unicode 表示,任何可以用 Unicode 表示的字符串都可以用 UTF-8 编码。

反之则不然。无法将任意 Unicode 字符串转换为任何其他(标准)编码。

Unicode 包含 1,114,112 个代码点。至少需要三个字节来表示这么多不同的点。 UTF-8 可以表示这些代码点中的任何一个。

GB2312(又名简体中文)包含6000+码位,所以有很多Unicode码位在GB2312中没有对应的条目。这就是为什么 UTF-8 到 GB3213 编码总是有损的原因。所以理论上往返转换是不可能的。

也就是说,有从 UTF-8 到 GB2312 的“尽力而为”的转换器,没有理由不让它们不依赖于平台。谷歌搜索 UTF-8 to GB2312 conversion 发现了很多可能性,其中大部分不依赖于任何特定平台。

我建议您进行此搜索并选择满足您需求的结果。

一种独立于平台的编码转换解决方案是 boost.locale对它可以为您做什么的完整解释超出了 Stack Overflow 答案的范围即使我使用边距。

补充阅读:this page provides useful background information for understanding string encoding issues .

关于c++ - 有什么办法可以在 utf-8 和平台无关的纯字符串之间进行转换吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41755942/

相关文章:

c++ - Qt C++ 写入/读取 "IBM037/CP037"

c++ - C++中曲线下的二维随机点

c++ - `constexpr` 和 `const` 的区别

C++11 std::function 比虚拟调用慢?

c++ - C++ 11中线程的延迟启动

java - "Fix"Java 中的字符串编码

c++ - 为什么 GCC 中 std::list O(n) 的 size() 方法?

c++ - 嵌套的 C++ for 循环与 openmp 并行化

c++ - DirectX:渲染到 Texture2DArray,并在计算着色器中从中加载

php - 将数组值从 ISO-8859-1 转换为 UTF8 以进行 JSON 编码