Luk*_*sen 21 c++ utf-8 literals string-literals c++11
来自维基百科:
为了在C++编译器中增强对Unicode的支持,char类型的定义已被修改为至少为存储UTF-8的8位编码所需的大小.
我想知道这对于编写便携式应用程序究竟意味着什么.写这个有什么区别吗?
const char[] str = "Test String";
Run Code Online (Sandbox Code Playgroud)
或这个?
const char[] str = u8"Test String";
Run Code Online (Sandbox Code Playgroud)
是否有任何理由不在代码中的每个字符串文字中使用后者?
当TestString中有非ASCII字符时会发生什么?
Ker*_* SB 24
编码"Test String"
是实现定义的系统编码(窄,可能是多字节编码).
编码u8"Test String"
始终是UTF-8.
这些例子并不十分清楚.如果你\U0010FFFF
在字符串中包含了一些Unicode文字(例如),那么你总是得到那些(编码为UTF-8),但它们是否可以用系统编码的字符串表示,如果是,它们的值是什么,是实现定义的.
如果它有帮助,想象一下你在EBCDIC机器上编写源代码.然后,文字"Test String"在源文件本身中始终是EBCDIC编码的,但是u8
-initialized数组包含UTF-8编码值,而第一个数组包含EBCDIC编码值.
Che*_*Alf 16
你引用维基百科:
为了在C++编译器中增强对Unicode的支持,char类型的定义已被修改为至少为存储UTF-8的8位编码所需的大小.
那么,"为了目的"是不正确的.由于C标准要求的范围,char
一直保证至少为8位,即CHAR_BIT
一直要求≥8位char
.这是(引用C++11§17.5.1.5/ 1)"纳入"C++标准.
如果我应该猜测改变措辞的目的,那就是为那些不知道依赖C标准的读者澄清事情.
关于u8
字面前缀的效果,它
影响可执行文件中字符串的编码,但是
不幸的是它不会影响类型.
因此,在这两种情况下"tørrfisk"
,u8"tørrfisk"
你得到一个.但在前一个字面值中,编码是为编译器选择的任何内容,例如,对于字符大小为9,使用拉丁语1(或Windows ANSI Western),字符为8个字节加上nullbyte.而在后一个字面值中,编码为保证是UTF-8,其中"ø"将用2或3个字节编码(我不记得确切),对于稍大的数组大小.char const[n]
编译器为平台选择自然的本机编码.在典型的POSIX系统上,它可能会选择ASCII,这可能取决于环境设置的ASCII范围之外的字符值.在大型机上,它可能会选择EBCDIC.比较从文件或命令行接收的字符串可能最适合本机字符集.在处理使用UTF-8显式编码的文件时,您可能最好使用u8"..."
字符串.
这就是说,随着近来有关字符的变化编码串的处理的基本假设在C和C++得到了破:每个内部角色对象(char
,wchar_t
用来表示一个字符,等等).对于UTF-8字符串来说,这显然不再正确,因为每个字符对象只表示某个字符的字节.因此,所有字符串操作,字符分类等功能都不一定适用于这些字符串.我们没有任何好的图书馆可以处理这些字符串以包含在标准中.
如果编译器的执行字符集设置为UTF-8,u8
使用与不使用没有区别,因为编译器在两种情况下都会将字符转换为UTF-8。
但是,如果编译器执行字符集是系统的非 UTF8 代码页(例如 Visual C++ 的默认值),则在u8
省略时可能无法正确处理非 ASCII 字符。例如,转换为宽字符串会在 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.
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
22111 次 |
最近记录: |