【发布时间】:2011-10-28 05:23:00
【问题描述】:
谁能解释为什么通用字符文字(例如“\u00b1”)被编码为 UTF-8 字符字符串?为什么下面会打印加号/减号?
#include <iostream>
#include <cstring>
int main()
{
std::cout << "\u00b1" << std::endl;
return 0;
}
这与我当前的语言环境有关吗?
【问题讨论】:
标签: c++
谁能解释为什么通用字符文字(例如“\u00b1”)被编码为 UTF-8 字符字符串?为什么下面会打印加号/减号?
#include <iostream>
#include <cstring>
int main()
{
std::cout << "\u00b1" << std::endl;
return 0;
}
这与我当前的语言环境有关吗?
【问题讨论】:
标签: c++
2.13.2。 [...]
5/ 通用字符名被转换为编码,在 命名字符的执行字符集。如果没有 这样的编码,universal-character-name 被翻译成 实现定义的编码。 [注意:在翻译阶段 1,a 每当实际扩展时,都会引入通用字符名称 在源文本中遇到字符。因此,所有扩展 字符是根据通用字符名称来描述的。 但是,实际的编译器实现可能会使用自己的原生 字符集,只要得到相同的结果。 ]
和
2.2。 [...] 执行字符集成员的值 是实现定义的,任何其他成员都是 特定于语言环境。
简而言之,您的问题的答案在您的编译器文档中。然而:
2.2。 2/由universal-character-name指定的字符 \UNNNNNNNN 是 ISO/IEC 中字符短名称的字符 10646 是 NNNNNNNN;指定的字符 通用字符名称 \uNNNN 是其字符的那个字符 ISO/IEC 10646 中的简称为 0000NNNN。如果十六进制值为 通用字符名称小于 0x20 或在 0x7F-0x9F 范围内 (含),或者如果通用字符名称指定一个字符 在基本源字符集中,则程序格式错误。
所以您可以保证您命名的字符被翻译成实现定义的编码,可能是特定于语言环境的。
【讨论】:
\u00b1 是 ± 符号,因为无论语言环境如何,它都是正确的 unicode 表示。
您的代码在ideone, see here。
【讨论】:
字符串字面量,例如"abcdef" 是简单的字节数组(const char[] 类型)。编译器将其中的非 ASCII 字符编码为实现定义的内容。谣言说 Visual C++ 使用当前 Windows 的 ANSI 代码页,而 GCC 使用 UTF-8,所以你可能使用 GCC :)
因此,\uABCD 在编译时由编译器解释并转换为该编码中的相应值。 IE。它可以将一个或多个字节放入字节数组中:
sizeof("\uFE58z") == 3 // visual C++ 2010
sizeof("\uFE58z") == 5 // gcc 4.4 mingw
然而,cout 将如何打印字节数组,取决于区域设置。您可以通过std::ios_base::imbue() 调用更改流的区域设置。
【讨论】:
z? (诚实的问题)
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++ 定义了可用于表示这些字符的三字符序列:
[ ??(
] ??)
{ ??<
} ??>
| ??!
\ ??/
# ??=
^ ??'
~ ??-
三字母序列在编译过程的早期就被映射到相应的基本源字符。
C++ 还具有“替代标记”的概念,可用于将标记替换为其他标记。代币及其替代品的列表如下:
{ <%
} %>
[ <:
] :>
# %:
## %:%:
&& and
| bitor
|| or
^ xor
~ compl
& bitand
&= and_eq
|= or_eq
^= xor_eq
! not
!= not_eq
另一个想法是“基本执行字符集”。这包括所有基本的源字符集,以及用于警报、退格、回车和 null 的控制字符。 “执行字符集”是基本执行字符集加上附加的实现定义字符。这个想法是源字符集用于定义 C++ 程序本身,而执行字符集用于 C++ 应用程序执行时。
鉴于此概念,可以在正在运行的程序中操作其他字符,例如来自西里尔文或希腊文的字符。字符常量可以使用以下任何一种来表示:
\137 octal
\xabcd hexadecimal
\u12345678 universal character name (ISO/IEC 10646)
\u1234 -> \u00001234
此表示法使用源字符集来定义执行集字符。通用字符名称可用于标识符(如果是字母)和字符文字中:
'\u1234'
L'\u2345'
您的本地 C++ 编译器中可能尚不存在上述功能。在开发国际化应用程序时,它们是重要的考虑因素。
【讨论】: