在使用Visual Studio 2015的Windows上
parse = icBuilder.parse(new InputSource(new StringReader(xmlString)));
“\ u00dc”与 u8“\ u00dc”或“Ü”不一样的 U8的 “u”
显然,通常的字符串文字的默认编码不是UTF-8(可能是UTF-16),我不能只比较两个std :: string而不知道它的编码,即使它们具有相同的语义。
在unicode-enable c ++应用程序开发中执行此类字符串比较的做法是什么?
例如这样的API:
// Ü
// UTF-8 (hex) 0xC3 0x9C
// UTF-16 (hex) 0x00DC
// UTF-32 (hex) 0x000000DC
using namespace std::string_literals;
const auto narrow_multibyte_string_s = "\u00dc"s;
const auto wide_string_s = L"\u00dc"s;
const auto utf8_encoded_string_s = u8"\u00dc"s;
const auto utf16_encoded_string_s = u"\u00dc"s;
const auto utf32_encoded_string_s = U"\u00dc"s;
assert(utf8_encoded_string_s == "\xC3\x9C");
assert(narrow_multibyte_string_s == "Ü");
assert(utf8_encoded_string_s == u8"Ü");
// here is the question
assert(utf8_encoded_string_s != narrow_multibyte_string_s);
其他程序可以使用UTF-8中的std :: string或默认(UTF-16?)编码来调用isAvailable。我怎么能保证做正确的比较?
我可以在编译时检测到任何编码不匹配吗?
注意:我更喜欢C ++ 11/14。 首选std :: string而不是std :: wstring
答案 0 :(得分:2)
"\u00dc"
都是char[]
编码的,因此在不同的机器上可能会有所不同。在Windows上,这往往是操作系统的默认Ansi编码,或者它可能是源文件保存为的编码。
L"\u00dc"
是一个wchar_t[]
,编码为UTF-16或UTF-32,具体取决于编译器对wchar_t
的定义(在Windows上为16位,因此为UTF-16) )。
u8"\u00dc"
是UTF-8编码的char[]
。
u"\u00dc"
是UTF-16编码的char16_t[]
。
U"\u00dc"
是UTF-32编码的char32_t[]
。
""s
后缀只返回std::string
,std::wstring
,std::u16string
或std::u32string
,具体取决于char[]
,{{ 1}},wchar_t[]
或char16_t[]
传递给它。
比较两个字符串时,请确保它们首先使用相同的编码。这对于您的char32_t[]
/ char[]
数据尤其重要,因为它可以是任意数量的8位编码,具体取决于所涉及的系统。如果应用程序本身生成字符串,这不是一个问题,但如果一个或多个字符串来自外部源(文件,用户输入,网络协议等),这一点很重要。
在您的示例中,std::string
和"\u00dc"
不一定保证生成相同的"Ü"
序列,具体取决于编译器如何解释这些不同的文字。但即使他们这样做(在你的例子中似乎就是这种情况),他们都不会产生UTF-8(你必须采取额外的措施来强迫它),这就是你与char[]
的比较的原因。失败。
因此,如果您希望字符串文字为UTF-8,请使用utf8_encoded_string_s
来确保。如果您从外部源获取字符串数据并且需要它是UTF-8,请尽快将其转换为代码中的UTF-8(如果尚未使用)(这意味着您必须知道所使用的编码)外部来源)。