C++ 文件编码如何影响C++;11个字符串文本?

C++ 文件编码如何影响C++;11个字符串文本?,c++,encoding,c++11,string-literals,C++,Encoding,C++11,String Literals,可以在C++11中编写UTF-8/16/32字符串文字,方法是在字符串文字前面分别加上u8/u/u。编译器必须如何解释在这些新类型的字符串文本中包含非ASCII字符的UTF-8文件?据我所知,该标准没有指定文件编码,仅此一点就足以使源代码中非ASCII字符的解释完全不确定,这使得该功能的用处稍小 我知道您仍然可以使用\unnn对单个unicode字符进行转义,但对于一个完整的俄语或法语句子(通常包含多个unicode字符)来说,这种转义的可读性不是很高 我从各种渠道了解到,u在当前的Window

可以在C++11中编写UTF-8/16/32字符串文字,方法是在字符串文字前面分别加上
u8
/
u
/
u
。编译器必须如何解释在这些新类型的字符串文本中包含非ASCII字符的UTF-8文件?据我所知,该标准没有指定文件编码,仅此一点就足以使源代码中非ASCII字符的解释完全不确定,这使得该功能的用处稍小

我知道您仍然可以使用
\unnn
对单个unicode字符进行转义,但对于一个完整的俄语或法语句子(通常包含多个unicode字符)来说,这种转义的可读性不是很高

我从各种渠道了解到,
u
在当前的Windows实现中应等同于
L
,在Linux实现中应等同于
u
。因此,考虑到这一点,我还想知道旧字符串文字修饰符所需的行为是什么

对于代码示例:

string utf8string a = u8"L'hôtel de ville doit être là-bas. Ça c'est un fait!";
string utf16string b = u"L'hôtel de ville doit être là-bas. Ça c'est un fait!";
string utf32string c = U"L'hôtel de ville doit être là-bas. Ça c'est un fait!";

在一个理想的世界中,所有这些字符串都产生相同的内容(如:在转换后的字符),但是我的C++经验告诉我,这是最明确的实现定义,可能只有第一个将做我想要的。p> 在GCC中,使用

-finput charset=charset

设置输入字符集,用于将输入文件的字符集转换为GCC使用的源字符集。如果区域设置未指定,或者GCC无法从区域设置获取此信息,则默认为UTF-8。这可以由区域设置或此命令行选项覆盖。当前,如果存在冲突,则命令行选项优先。字符集可以是系统的“iconv”库例程支持的任何编码

还可以查看选项
-fexec charset
-fwide exec charset

最后,关于字符串文字:

char     a[] = "Hello";
wchar_t  b[] = L"Hello";
char16_t c[] = u"Hello";
char32_t d[] = U"Hello";
字符串文本的大小修饰符(
L
u
u
)仅确定文本的类型

编译器必须如何解释在这些新类型的字符串文本中包含非ASCII字符的UTF-8文件。据我所知,该标准没有指定文件编码,仅此一点就足以使源代码中非ASCII字符的解释完全不确定,这使得该功能的用处稍小

从n3290开始,翻译的2.2个阶段[法律阶段]

物理源文件字符在 实现定义方式,以基本源字符集 (为行尾指示器引入新行字符)如果 必要的。已接受物理源文件字符集 实现定义。[这里有一点关于三角图的信息]有任何来源吗 替换不在基本源字符集(2.3)中的文件字符 通过指定该字符的通用字符名。(一) 实现可以使用任何内部编码,只要实际 源文件中遇到扩展字符,并且相同 扩展字符,在源文件中表示为 通用字符名(即使用\uxxx表示法)是 以同等方式处理,除非此替换在 原始字符串文字。)

有许多标准术语用于描述实现如何处理编码。以下是我对所发生事情的简单、逐步的描述:

物理源文件字符在 实现定义方式,以基本源字符集[…]

文件编码问题是手工解决的;该标准只关心基本的源字符集,为实现提供了空间

任何来源 替换不在基本源字符集(2.3)中的文件字符 通过指定该字符的通用字符名

基本源代码集是一个简单的允许字符列表。它不是ASCII码(请参阅下文)。不在此列表中的任何内容都将“转换”(至少在概念上)为
\uxxx
形式

因此,无论使用哪种文字或文件编码,源代码都会在概念上转换为基本字符集+一组
\uxxx
。我之所以这样说,是因为实现的实际操作通常更简单,例如,因为它们可以直接处理Unicode。重要的一点是,标准所称的扩展字符(即,不是来自基本源代码集)在使用时应该与其等价的
\uxxx
形式无法区分。请注意,C++03在例如EBCDIC平台上可用,因此您从一开始就用ASCII进行推理是有缺陷的

最后,我描述的过程也适用于(非原始)字符串文本。这意味着您的代码相当于您编写的:

string utf8string a = u8"L'h\u00F4tel de ville doit \u00EAtre l\u00E0-bas. \u00C7a c'est un fait!";
string utf16string b = u"L'h\u00F4tel de ville doit \u00EAtre l\u00E0-bas. \u00C7a c'est un fait!";
string utf32string c = U"L'h\u00F4tel de ville doit \u00EAtre l\u00E0-bas. \u00C7a c'est un fait!";

原则上,编码问题只在您通过使字符串对人类可见来输出字符串时才起作用,这不是编程语言如何定义的问题,因为它的定义只处理编码计算。因此,当您决定在编辑器中看到的内容是否与在输出中看到的内容相同(任何类型的图像,无论是在屏幕上还是在pdf中),您应该问问自己,您的用户交互库和操作系统的编码方式采用了哪种约定。(例如,这里有这样的信息:在Qt5中,如果QString的老式字符串文本的内容在源文件中编码为utf8,则您作为应用程序用户看到的内容与作为其程序员看到的内容是一致的,除非在应用程序执行过程中打开另一个设置)

作为结论,我认为Kerrek SB是对的,而Damon是错的