6

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

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

产生以下输出:

(奇怪的]

因此翻译 '??)' -> ']'

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

有人有解释吗?

  • search : '问号,问号,右大括号' c c++ 字符串文字
4

9 回答 9

17

您所看到的称为trigraph

在成年人的书面语言中,任何情况下一个问号就足够了。一次不要使用超过一个,你将永远不会再看到这个。

GCC 默认忽略三元组,因为几乎没有人故意使用它们。使用该选项启用它们-trigraph,或告诉编译器使用该-Wtrigraphs选项警告您有关它们的信息。

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

于 2009-11-03T19:03:39.740 回答
6

避免三元组意外的简单方法:拆分“??” 字符串文字分为两个:

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

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

标准报价

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

这是一个三字形

于 2009-11-03T19:04:02.010 回答
4

??) 是一个三元组

于 2009-11-03T19:04:22.407 回答
4

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

char* strange = "(Strange?\?)";
于 2009-11-03T19:06:42.263 回答
3

这是一个三元组

于 2009-11-03T19:04:29.333 回答
3

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

于 2009-11-03T19:04:29.590 回答
2

正如多次提到的,你被三合符咬伤了。有关更多信息,请参阅此先前的 SO 问题:

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

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

事实上,这就是那个转义序列的原因,如果你不知道那些该死的三元组,这有点神秘。

于 2009-11-03T19:40:35.097 回答
1

在尝试在 GCC 上进行交叉编译时,它选择了我的序列作为三元组

所以我现在需要做的就是弄清楚如何在默认情况下在项目中禁用它,因为我只能看到它给我带来了问题。(无论如何我都在使用美式键盘布局)

GCC 的默认行为是忽略但给出警告,这更加理智,据我所知,这确实是 Visual Studio 2010 将采用的标准。

于 2009-11-03T19:45:12.823 回答