您可以在C ++ 11中编写UTF-8/16/32字符串文字,方法是将字符串文字分别加上u8
/ u
/ U
。编译器如何解释这些新类型的字符串文字中包含非ASCII字符的UTF-8文件?我理解标准没有指定文件编码,而这个事实本身就会使源代码中非ASCII字符的解释完全不确定,这使得这个特性变得不那么有用了。
我知道您仍然可以使用\uNNNN
转义单个unicode字符,但这对于完整的俄语或法语句子来说并不是非常易读,因为它通常包含多个unicode字符。
我从各种来源了解到,u
应该与当前Windows实施中的L
等效,并且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!";
。 Linux实现。因此,考虑到这一点,我也想知道旧的字符串文字修饰符所需的行为是什么......
对于代码示例猴子:
{{1}}
在理想的世界中,所有这些字符串都产生相同的内容(如:转换后的字符),但我使用C ++的经验告诉我,这绝对是实现定义的,并且可能只有第一个会做我想做的事情。
答案 0 :(得分:8)
在GCC中,使用-finput-charset=charset
:
设置输入字符集,用于从输入文件的字符集转换为GCC使用的源字符集。如果区域设置未指定,或GCC无法从区域设置获取此信息,则默认值为UTF-8。这可以通过语言环境或此命令行选项覆盖。目前,如果存在冲突,命令行选项优先。 charset可以是系统的“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
)的尺寸修饰符仅确定文字的类型。
答案 1 :(得分:5)
编译器如何解释在这些新类型的字符串文字中包含非ASCII字符的UTF-8文件。我理解标准没有指定文件编码,而这个事实本身就会使源代码中非ASCII字符的解释完全不确定,这使得这个特性变得不那么有用了。
从n3290,2.2阶段的翻译[lex.phases]
物理源文件字符映射在一个 实现定义的方式,基本源字符集 (引入行尾指标的换行符)if 必要。接受的物理源文件字符集是 实现定义。 [这里有一些关于三字母的内容。]任何来源 不替换基本源字符集(2.3)中的文件字符 通过指定该角色的通用字符名称。 (一个 实现可以使用任何内部编码,只要是实际的 源文件中遇到的扩展字符,并且相同 扩展字符在源文件中表示为 通用字符名称(即使用\ uXXXX表示法)是 处理等效,除非这个替换在a。中被还原 原始字符串文字。)
有很多标准术语用于描述实现如何处理编码。这是我尝试对所发生的事情进行更简单,逐步的描述:
物理源文件字符映射在一个 实现定义的方式,基本源字符集[...]
文件编码问题是handwaved;标准只关心基本的源字符集,并为实现提供了空间。
任何来源 不替换基本源字符集(2.3)中的文件字符 通过指定该角色的通用字符名称。
基本源集是允许字符的简单列表。 它不是ASCII (见进一步说明)。不在此列表中的任何内容都会“转换”(至少在概念上)为\uXXXX
形式。
因此,无论使用何种文字或文件编码,源代码在概念上都会转换为基本字符集+一堆\uXXXX
。我在概念上说,因为实现的实际操作通常更简单,例如因为他们可以直接处理Unicode。重要的是,标准称为扩展字符(即不是来自基本源集)的内容在使用时应与其等效的\uXXXX
形式无法区分。请注意,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!";
答案 2 :(得分:0)
原则上,编码问题仅在输出字符串时使问题变得很重要,这不是编程语言如何定义的问题,因为它的定义只涉及编码计算。所以,当你决定,你在编辑器中看到的内容是否与你在输出中看到的相同(任何类型的图像,无论是在屏幕上还是在pdf中),你应该问自己哪个约定用户交互库和操作系统编码的方式假设。 (例如,这是一种信息for Qt5:使用Qt5,你看到的应用程序的用户和你看到的程序员一致,如果你的老式字符串文字的内容QStrings在源文件中编码为utf8,除非您在应用程序执行过程中打开其他设置。
作为结论,我认为Kerrek SB是对的,Damon是错的:实际上,在代码中指定文字的方法应该指定其类型,而不是源文件中用于填充其内容的编码,因为文字的类型与计算所做的有关。像u"string"
之类的东西只是一个“unicode codeunits”(即char16_t
类型的值)的数组,无论操作系统或任何其他服务软件以后对它们做什么,然而他们的工作找你或者为其他用户。你只是遇到了为自己添加另一个约定的问题,它使计算中数字的“含义”(即,它们呈现Unicode的代码)之间的对应关系,以及当你在文本编辑器中工作时它们在屏幕上的表示。您作为程序员如何以及是否使用“意义”是另一个问题,如何强制执行其他对应关系自然会被实现定义,因为它与编码计算无关,只有工具的舒适性和# 39;使用。