C / C ++字符串文字中的未知元字符?

我使用以下代码段创建了一个新项目:

char* strange = "(Strange??)"; cout << strange << endl; 

产生以下输出:

(奇怪]

因此翻译’??)’ – >’]’

调试它显示我的char *字符串文字实际上是该值,它不是流转换。 这显然不是我见过的元字符序列。 也许是某种Unicode或宽字符序列? 我不这么认为……我已经尝试禁用所有相关的项目设置无济于事。

有人有解释吗?

  • 搜索:’问号,问号,闭括号’c c ++ string literal

你所看到的被称为三卦

在成年人的书面语言中,一个问号就足以应对任何情况。 不要一次使用多个,你再也不会看到这个。

GCC默认忽略了三字母,因为几乎没有人故意使用它们。 使用-trigraph选项启用它们,或者告诉编译器使用-Wtrigraphs选项警告它们。

Visual C ++ 2010默认情况下也会禁用它们,并提供/Zc:trigraphs来启用它们。 我在以前的版本中找不到任何关于启用或禁用它们的方法。

避免三角形惊喜的简单方法:拆分“??” 字符串文字分为两部分:

 char* strange = "(Strange??)"; char* strange2 = "(Strange?" "?)"; /* ^^^ no punctuation */ 

编辑
gcc有一个选项来警告三字符: -Wtrigraphs (启用-Wall也)
结束编辑

来自标准的报价

     5.2.1.1 Trigraph序列
 1在进行任何其他处理之前,每次发生一次
    以下三个字符序列(称为三字符序列13))
    被替换为相应的单个字符。
            ?? =#??)?? ??!  |
            ??([??'^ ??>}
            ?? / \ ?? ?? {{??  - 〜
    没有其他三字符序列存在。 每个? 那不是开始的
    上面列出的三字母不会改变。
     5.1.1.2翻译阶段
 1翻译语法规则的优先级由
    以下阶段。
          1.物理源文件多字节字符映射在一个
              实现定义的方式,源字符集
               (为行尾指标引入换行符)
              如有必要。  Trigraph序列被相应的替换
              单字符内部表示。

这是一个Trigraph !

??)是一个三角形 。

这是三角形的支持。 你可以通过转义任何字符来防止三元组解释:

 char* strange = "(Strange?\?)"; 

这是一个三角形 。

Trigraphs是原因。 文章中关于C的讨论也适用于C ++

如上所述,你被三字母咬伤了。 有关更多信息,请参阅此前的SO问题:

  • C ++中Trigraph序列的目的是什么?

您可以使用’\?’来解决问题 ‘?’的转义序列 字符:

 char* strange = "(Strange\?\?)"; 

事实上,这就是逃脱序列的原因,如果你不知道那些该死的三角形,这有点神秘。

在尝试在GCC上进行交叉编译时,它将我的序列选为三字符 :

所以我现在需要做的就是弄清楚如何在项目中禁用它,因为我只能看到它为我创建问题。 (无论如何,我正在使用美国键盘布局)

GCC上的默认行为是忽略但是会发出警告,这更加明智,而且就我所知,Visual Studio 2010确实将采用这种警告作为标准。