打印通用字符

时间:2011-08-16 16:14:02

标签: c++

有人可以解释为什么通用字符文字(例如“\ u00b1”)被编码为字符串为UTF-8吗?为什么以下打印加号/减号?

#include <iostream>
#include <cstring>
int main()
{
  std::cout << "\u00b1" << std::endl;
  return 0;
}

这与我当前的语言环境有关吗?

4 个答案:

答案 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 ++编译器中可能尚不存在上述功能。在开发国际化应用程序时,必须考虑它们。