是U8字符串常量在C ++ 11必要(Is the u8 string literal necess

2019-07-03 22:41发布

从维基百科 :

为了提高在C ++编译器支持Unicode的目的,类型炭的定义已被修饰为至少需要存储UTF-8的八位编码的大小。

我想知道究竟是什么,这意味着用于编写便携式应用。 有没有写这个有什么区别

const char[] str = "Test String";

或这个?

const char[] str = u8"Test String";

是否有任何理由不使用后者为每串代码中的文字?

当有将TestString内非ASCII字符,会发生什么?

Answer 1:

的编码"Test String"是实现定义的系统编码(窄,可能多字节一个)。

的编码u8"Test String"始终是UTF-8。

这些例子并不十分有说服力。 如果包括了一些Unicode的文字(如\U0010FFFF )到字符串,那么你就会让那些(编码为UTF-8),但他们是否能在系统编码的字符串来表示,如果是什么他们的价值会是,是实现定义。

如果有帮助,想象一下你正在编写一个EBCDIC机的源代码。 然后字面“测试字符串”是源文件本身中总是EBCDIC编码,但u8 -initialized数组包含UTF-8编码的值,而第一阵列包含EBCDIC编码的值。



Answer 2:

你引用维基百科:

为了提高在C ++编译器支持Unicode的目的,类型炭的定义已被修饰为至少需要存储UTF-8的八位编码的大小。

那么,“为宗旨,以”是不正确的。 char一直保证是至少8位,即, CHAR_BIT一直需要为≥8,由于所需的范围内char C标准。 这是(报价C ++ 11§17.5.1.5/ 1)“引入”到C ++标准。

如果我猜对措辞的这种变化的目的 ,这将是刚刚澄清事情的读者不知道在C标准的依赖。

至于效果u8文字前缀,它

  • 影响在可执行文件中字符串的编码,但

  • 遗憾的是它影响类型。

因此,在这两种情况下"tørrfisk"u8"tørrfisk"你得到一个char const[ n ] 但在前者字面编码是任何被选择用于编译器,例如用拉丁语1(或Windows ANSI西),这将是用于字符加上一个nullbyte 8个字节,对于数组大小9.虽然在后者的文字编码是保证是UTF-8,其中“O”将与2或3个字节(I不记得确切地),对于稍大阵列大小进行编码。



Answer 3:

编译器选择本地编码天然的平台。 在典型的POSIX系统中,可能会选择ASCII和可能取决于环境的设置为ASCII范围之外的字符值的东西。 在大型机上它可能会选择EBCDIC。 收到比较字符串,例如,从文件或命令行可能会工作最好与本地字符集。 当处理文件使用UTF-8编码明确你,然而,可能是最好关闭使用u8"..."字符串。

这就是说,随着近来有关字符的变化编码串的处理在C语言的基本假设和C ++得到了破:每个内部角色对象( charwchar_t ,等等)用于表示一个字符。 这显然是不正确的了一个UTF-8字符串whee每个字符对象只是代表了一些字符的字节。 因此,所有的字符串操作,字符分类等功能不一定会在这些字符串工作。 我们没有任何好的库排着队来处理这种字符串纳入标准。



Answer 4:

如果设置的编译器执行字符设置为UTF-8,它是没有区别,如果u8使用与否,因为编译器在两种情况下,字符转换为UTF-8。

但是,如果编译器执行字符集是系统的非UTF8代码页(默认为如VISUAL C ++),则非ASCII字符可能无法正确处理时, u8被省略。 例如,转换为宽字符串将在VS15崩溃如:

std::string narrowJapanese("スタークラフト");
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> convertWindows;
std::wstring wide = convertWindows.from_bytes(narrowJapanese); // Unhandled C++ exception in xlocbuf.


文章来源: Is the u8 string literal necessary in C++11