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

时间:2009-11-03 19:00:51

标签: c++ c visual-c++ trigraphs

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

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

产生以下输出:

  

(奇怪]

因此翻译'??)' - &gt; ']'

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

有人有解释吗?

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

9 个答案:

答案 0 :(得分:17)

您所看到的内容称为trigraph

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

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

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

答案 1 :(得分:6)

避免三线突然出现的简单方法:拆分“??”字符串文字为二:

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

修改
gcc可以选择警告三字符:-Wtrigraphs(也可以-Wall启用)
结束编辑

标准报价

    5.2.1.1 Trigraph sequences
1   Before any other processing takes place, each occurrence of one of the
    following sequences of three characters (called trigraph sequences13))
    is replaced with the corresponding single character.
           ??=      #               ??)      ]               ??!      |
           ??(      [               ??'      ^               ??>      }
           ??/      \               ??<      {               ??-      ~
    No other trigraph sequences exist. Each ? that does not begin one of
    the trigraphs listed above is not changed.
    5.1.1.2 Translation phases
1   The precedence among the syntax rules of translation is specified by
    the following phases.
         1.   Physical source file multibyte characters are mapped, in an
              implementation-defined manner, to the source character set
              (introducing new-line characters for end-of-line indicators)
              if necessary. Trigraph sequences are replaced by corresponding
              single-character internal representations.

答案 2 :(得分:5)

这是一个Trigraph

答案 3 :(得分:4)

??)是trigraph

答案 4 :(得分:4)

那是trigraph支持。您可以通过转义任何字符来防止三元组解释:

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

答案 5 :(得分:3)

这是trigraph

答案 6 :(得分:3)

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

答案 7 :(得分:2)

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

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

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

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

答案 8 :(得分:1)

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

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

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