【发布时间】:2009-05-07 15:48:21
【问题描述】:
我知道 ICU 和代码项目中的 utf8 等小型库(忘记确切名称),但这些都不是我想要的。
我真正想要的是像重症监护室但以更友好的方式包裹起来的东西。
具体来说:
- 完全面向对象
- c++ 标准流的实现,或至少执行相同角色的东西。
- 可以根据区域设置的方式格式化时间、日期等(例如,英国的 dd/mm/yy 和美国的 mm/dd/yy)。
- 让我选择字符串的“内部”编码,例如,我可以让它在 windows 上使用 UTF-16,以避免在 windows API 和 DirectX 之间传递字符串时进行大量转换
- 在编码之间轻松转换字符串
如果不存在这样的库,是否可以使用标准 c++ 类将 ICU 包装起来,因此我可以创建一个与 std::string 和 std::wstring 具有相同用法的 ustring,并实现版本的流(最好与现有的完全兼容,即我可以将它传递给一个期望 std::ostream 的函数,它将在其内部格式和 ascii(或 utf-8)之间进行转换) ?假设可能需要做多少工作?
编辑: 还查看了 c++0x 标准并注意到 utf8、utf16 和 utf32 的文字,这是否意味着标准库(例如字符串、流等)将完全支持这些编码以及它们之间的转换?如果是这样,有人知道 Visual Studio 支持这些功能需要多长时间?
编辑2: 至于使用现有的 c++ 支持,我会查找 locale 和 facet 的东西。
我遇到的一个问题是,当使用围绕 wchar_t 定义的流时,它在 windows 下是 2 个字节的文件 i/o 但是它似乎仍然对它们自己的文件使用 ascii。
std::wofstream file(L"myfile.txt", std::ios::out);
file << L"Hello World!" << std::endl;
导致文件中出现以下十六进制
48 65 6C 6C 6F 20 57 6F 72 6C 64 0D 0A
这显然是 ascii 而不是预期的 utf-16 输出:
FF FE 48 00 65 00 6C 00 6C 00 6F 00 20 00 57 00 6F 00 72 00 6C 00 64 00 0D 00 0A 00
【问题讨论】:
-
UTF-16 文本实际上已转换为本地 8 位编码!因此,您不要将 utf-16 写入文件。不要忘记调用 std::locale::global(std::locale());
-
好的,那么我如何告诉它我想要文件的编码是什么?我尝试了你上面提到的 std::local... 但它似乎没有任何效果:(
-
好的,例如,如果系统语言环境
ru_RU.UTF-8,那么编码是utf-8,如果是ru_RU.KOI-8,那么它就是KOI。您还可以指定其他语言环境:locale::globale(locale("de_DE.ISO-8859-1"));(注意,我使用 POSIX 名称语言环境名称,对于 Windows,您应该检查语言环境名称是什么 -
好的,那么我如何获取当前语言环境(en_Us、en_Uk 等)并将其设置为 utf-16 用于宽文件 io(以及 assci/utf-8 用于窄流)