在我的应用程序中,我必须不断地在之间转换字符串std::string
and std::wstring
由于不同的 API(boost、win32、ffmpeg 等)。特别是对于 ffmpeg,字符串以 utf8->utf16->utf8->utf16 结尾,只是为了打开文件。
由于 UTF8 向后兼容 ASCII,我认为我始终以 UTF-8 存储所有字符串std::string
并且只转换为std::wstring
当我必须调用某些不寻常的函数时。
这工作得很好,我实现了 utf8 的 to_lower、to_upper、iequals。然而后来我遇到了几个死胡同 std::regex 和常规字符串比较。为了使其可用,我需要实现一个自定义ustring
基于 std::string 的类,重新实现所有相应的算法(包括正则表达式)。
基本上我的结论是 utf8 不太适合一般用途。而目前的std::string/std::wstring
很混乱。
但是,我的问题是为什么默认std::string
and ""
不是直接改成使用UTF8吗?特别是 UTF8 向后兼容?是否有一些编译器标志可以做到这一点?当然,stl 实现需要自动调整。
我看过 ICU,但它与假设 basic_string 的 api 不太兼容,例如没有开始/结束/c_str 等...
主要问题是内存中表示和编码的合并。
没有一种 Unicode 编码真正适合文本处理。用户通常会关心字素(屏幕上的内容),而编码是根据代码点定义的......并且某些字素由多个代码点组成。
因此,当有人问:第 5 个字符是什么时"Hélène"
(法国名字)这个问题很令人困惑:
- 从字素的角度来说,答案是
n
.
- 就代码点而言...这取决于
é
and è
(它们可以表示为单个代码点,也可以使用变音符号表示为一对......)
根据问题的来源(屏幕前的最终用户或编码例程),响应是完全不同的。
因此,我认为真正的问题是为什么我们在这里讨论编码?
今天它已经没有意义了,我们需要两个“视图”:字素和代码点。
不幸的是std::string
and std::wstring
接口是从人们认为 ASCII 就足够的时代继承下来的,所取得的进展并没有真正解决问题。
我什至不明白为什么应该指定内存中表示,它是一个实现细节。用户需要的只是:
- 能够以 UTF-* 和 ASCII 读/写
- 能够处理字素
- 能够编辑字素(管理变音符号)
...谁关心它是如何表示的?我以为好的软件都是建立在封装之上的?
好吧,C 很关心,我们想要互操作性……所以我想当 C 关心的时候它就会被修复。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)