我希望我的程序尽可能便携。我在字符串中搜索重音字符,例如è.这可能是个问题吗?是否有等效于 HTML 实体的 C++?
它将在 switch 语句中使用,例如:
switch(someChar) //someChar is of type char
{
case 'é' :
x = 1;
break;
case 'è' :
...
}
最佳答案
在 C++ 源代码中使用非 ASCII 字符的主要问题是编译器必须知道用于源代码的编码。如果源是 7 位 ASCII,那么它通常无关紧要,因为大多数编译器默认情况下都假定 ASCII 兼容编码。
此外,并非所有编译器都可以在编码方面进行配置,因此两个编译器可能会无条件地使用不兼容的编码,这意味着使用非 ASCII 字符可能会导致源代码无法与两者一起使用。
因此,请考虑如果要搜索的字符串是 UTF-8(可能是因为执行字符集是 UTF-8),那么您的代码在搜索重音字符时会发生什么情况。无论字 rune 字 'é' 是否按您的预期工作,您都不会找到重音字符,因为重音字符不会由任何单个字节表示。相反,您必须搜索各种字节序列。
C++ 允许在字符和字符串文字中使用不同类型的转义。通用字符名称允许您指定一个 Unicode 代码点,并且将完全按照该字符出现在源代码中的方式进行处理。例如
\u00E9
或 \U000000E9
.(其他一些语言有
\u
来支持高达 U+FFFF 的代码点,但缺乏 C++ 对超出此范围的代码点的支持,或者让您使用代理代码点。您不能在 C++ 中使用代理代码点,而 C++ 有\U 变体来支持直接所有代码点。)UCN 也应该在字符和字符串文字之外工作。在此类文字之外,UCN 仅限于不在基本源字符集中的字符。然而,直到最近,编译器还没有实现这个 (C++98) 特性。现在 Clang 似乎有相当完整的支持,MSVC 似乎至少有部分支持,GCC 声称通过选项
-fextended-identifiers
提供实验性支持。 .回想一下,UCN 应该与源中出现的实际字符一视同仁;因此,具有良好 UCN 标识符支持的编译器还允许您使用实际字符简单地编写标识符,只要编译器的源编码首先支持该字符。
C++ 还支持十六进制转义。这些是\x 后跟任意数量的十六进制数字。十六进制转义将表示单个整数值,就好像它是具有该值的单个代码点,并且不会对该值进行到执行字符集的转换。如果您需要表示独立于编码的特定字节(或 char16_t、或 char32_t、或 wchar_t)值,那么这就是您想要的。
还有八进制转义,但它们不如 UCN 或十六进制转义那么有用。
以下是在使用 ISO-8859-1 或 cp1252 编码的源文件中使用“é”时 Clang 显示的诊断信息:
warning: illegal character encoding in character literal [-Winvalid-source-encoding]
std::printf("%c\n",'<E9>');
^
Clang 仅将此作为警告发出,并且将直接输出带有源字节值的 char 对象。这样做是为了与非 UTF-8 源代码向后兼容。
如果您使用 UTF-8 编码的源代码,那么您会得到:
error: character too large for enclosing character literal type
std::printf("%c\n",'<U+00E9>');
^
Clang 检测到 UTF-8 编码对应于 Unicode 代码点 U+00E9,并且该代码点超出了单个字符可以容纳的范围,因此报告错误。 (Clang 也会对非 ASCII 字符进行转义,因为它确定运行它的控制台无法处理打印非 ASCII 字符)。
关于c++ - 在 C++ 源代码中使用重音字符是不是很糟糕?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11996127/