das*_*ird 0 c++ unicode non-ascii-characters icu c++11
我正在 C++11 中使用 Unicode,现在无法将 std::string 转换为 std::u32string。
\n\n我的代码如下:
\n\n#include <iostream>\n#include <string>\n#include <locale>\n#include "unicode/unistr.h"\n#include "unicode/ustream.h"\n\nint main()\n{\n constexpr char locale_name[] = "";\n setlocale( LC_ALL, locale_name );\n std::locale::global(std::locale(locale_name));\n std::ios_base::sync_with_stdio(false);\n std::wcin.imbue(std::locale());\n std::wcout.imbue(std::locale());\n\n std::string str="hello\xe2\x98\xba";\n\n std::u32string s(str.begin(),str.end());\n\n icu::UnicodeString ustr = icu::UnicodeString::fromUTF32(reinterpret_cast<const UChar32 *>(s.c_str()), s.size());\n std::cout << "Unicode string is: " << ustr << std::endl;\n\n std::cout << "Size of unicode string = " << ustr.countChar32() << std::endl;\n\n std::cout << "Individual characters of the string are:" << std::endl;\n for(int i=0; i < ustr.countChar32(); i++)\n std::cout << icu::UnicodeString(ustr.char32At(i)) << std::endl;\n\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n执行时输出为:(这不是预期的)
\n\nUnicode string is: hello\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\nSize of unicode string = 12\nIndividual characters of the string are:\nh\ne\nl\nl\no\n\xef\xbf\xbd\n\xef\xbf\xbd\n\xef\xbf\xbd\n\xef\xbf\xbd\n\xef\xbf\xbd\n\xef\xbf\xbd\n\xef\xbf\xbd\nRun Code Online (Sandbox Code Playgroud)\n\n请建议是否存在任何 ICU 库函数
\n输出是有道理的。想必您认为您正在定义一个包含 7 个字符的字符串?看一眼str.size()。您定义了一个包含 12 个字符的字符串!
即使您能够"hello\xe2\x98\xba"在程序中输入内容,该字符串文字也不仅仅包含七个字节。最后两个字符中的每一个都会扩展为多个字节,因为这些字符超出了扩展的 ASCII 范围(0 到 255 或 -128 到 127)。结果是一个 12 字节的字符串文字,它初始化一个 12 个字符的string,进而初始化一个 12 个字符的u32string。你已经破坏了你想要表现的角色。
示例:字符\'\xe2\x98\xba\'表示为三个字节\\0xE2\\0x98\\0xBA。如果char在您的系统上签名(可能),这三个字节的值为 -30、-104 和 -70。转换将char32_t这些值中的每一个提升为 32 位,然后将有符号转换为无符号,从而产生三个值4294967266、4294967192和4294967226。您可能想要的是将这些字节连接成单个char32_t值\\0x00E298BA。但是,您的转换不提供(重新)组合字节的机制。
同样,字符\'\'由四个字节表示\\0xF0\\0x9F\\0x98\\0x86。这些被转换为四个 32 位整数而不是单个值\\0xF09F9886。
为了获得您想要的结果,您需要告诉编译器将您的字符串文字解释为 7 个字符。尝试以下初始化s:
std::u32string s = U"hello\xe2\x98\xba";\nRun Code Online (Sandbox Code Playgroud)\n\nU字符串文字上的前缀告诉编译器每个字符代表一个 UTF-32 字符。这会产生所需的 7 个字符的字符串(假设您的编译器和编辑器同意字符编码,我认为这是相当可能的)。
免费调试要点:当您的输出不是您所期望的时,请检查每个阶段的数据以确保您的输入是您所期望的。
\n| 归档时间: |
|
| 查看次数: |
2718 次 |
| 最近记录: |