有人可以解释为什么通用字符文字(例如“\ u00b1”)被编码为字符串为UTF-8吗?为什么以下打印加号/减号?
#include <iostream>
#include <cstring>
int main()
{
std::cout << "\u00b1" << std::endl;
return 0;
}
这与我当前的语言环境有关吗?
答案 0 :(得分:4)
2.13.2。 [...]
5 /通用字符名称被转换为编码 名为的字符的执行字符集。如果没有 这样的编码,通用字符名称被翻译成一个 实现定义编码。 [注意:在翻译阶段1,a 每当实际扩展时引入通用字符名称 在源文本中遇到字符。因此,全部延伸 字符以通用字符名称描述。 但是,实际的编译器实现可能使用自己的本机 字符集,只要获得相同的结果即可。 ]
和
2.2。 [...]执行字符集成员的值 是实现定义的,任何其他成员都是 区域特异性的。
简而言之,您的问题的答案在您的编译器文档中。但是:
2.2。 2 /通用字符名称指定的字符 \ UNNNNNNNN是ISO / IEC中字符短名称的字符 10646是NNNNNNNN;由...指定的角色 universal-character-name \ uNNNN是其角色的角色 ISO / IEC 10646中的短名称是0000NNNN。如果为十六进制值 通用字符名称小于0x20或在0x7F-0x9F范围内 (包括),或者如果通用字符名称指定一个字符 在基本的源字符集中,程序是不正确的。
因此可以保证您命名的字符被转换为实现定义的编码,可能是特定于语言环境的。
答案 1 :(得分:1)
\u00b1
是±
符号,因为无论语言环境如何,它都是正确的unicode表示。
您的代码位于ideone, see here。
答案 2 :(得分:1)
字符串文字,例如"abcdef"
是简单的字节数组(类型为const char[]
)。编译器将非ASCII字符编码为实现定义的内容。谣言说Visual C ++使用当前Windows的ANSI代码页,GCC使用UTF-8,所以你可能在GCC上:)
因此,编译器在编译时解释\uABCD
并将其转换为该编码中的相应值。即它可以将一个或多个字节放入字节数组中:
sizeof("\uFE58z") == 3 // visual C++ 2010
sizeof("\uFE58z") == 5 // gcc 4.4 mingw
然而,cout
将如何打印字节数组取决于区域设置。您可以通过std::ios_base::imbue()
调用更改流的区域设置。
答案 3 :(得分:0)
C ++字符集
通过C ++的标准化,回顾一下处理字符集的语言中包含的一些机制是很有用的。这可能看起来像一个非常简单的问题,但有一些复杂性要与之抗衡。
要考虑的第一个想法是C ++中“基本源字符集”的概念。这被定义为:
all ASCII printing characters 041 - 0177, save for @ $ ` DEL
space
horizontal tab
vertical tab
form feed
newline
或总共96个字符。这些是用于组成C ++源程序的字符。
某些国家字符集,例如欧洲ISO-646字符集,会将其中一些字符位置用于其他字母。受影响的ASCII字符是:
[ ] { } | \
为了解决这个问题,C ++定义了可用于表示这些字符的三字符序列:
[ ??(
] ??)
{ ??<
} ??>
| ??!
\ ??/
# ??=
^ ??'
~ ??-
在编译过程的早期,Trigraph序列被映射到相应的基本源角色。
C ++也有“替代令牌”的概念,可用于替换其他人的令牌。令牌及其替代品列表如下:
{ <%
} %>
[ <:
] :>
# %:
## %:%:
&& and
| bitor
|| or
^ xor
~ compl
& bitand
&= and_eq
|= or_eq
^= xor_eq
! not
!= not_eq
另一个想法是“基本执行字符集”。这包括所有基本源字符集,以及alert,backspace,回车和null的控制字符。 “执行字符集”是基本执行字符集以及其他实现定义的字符。我们的想法是使用源字符集来定义C ++程序本身,而在执行C ++应用程序时使用执行字符集。
鉴于此概念,可以在正在运行的程序中操纵其他字符,例如来自西里尔语或希腊语的字符。字符常量可以使用以下任何一种表示:
\137 octal
\xabcd hexadecimal
\u12345678 universal character name (ISO/IEC 10646)
\u1234 -> \u00001234
此表示法使用源字符集来定义执行集字符。通用字符名称可用于标识符(如果是字母)和字符文字:
'\u1234'
L'\u2345'
您的本地C ++编译器中可能尚不存在上述功能。在开发国际化应用程序时,必须考虑它们。