6

次のコードセグメントで新しいプロジェクトを作成しました。

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

結果として次の出力が得られます。

(変]

したがって、'??)'->']'を翻訳します

デバッグすると、char *文字列リテラルが実際にはその値であり、ストリーム変換ではないことがわかります。これは明らかに私が今まで見たメタ文字シーケンスではありません。ある種のUnicodeまたはワイド文字シーケンス?しかし、そうは思いません...関連するすべてのプロジェクト設定を無効にしてみましたが無駄になりました。

誰か説明がありますか?

  • 検索:'疑問符、疑問符、中括弧を閉じる' cc++文字列リテラル
4

9 に答える 9

17

あなたが見ているものはトリグラフと呼ばれています。

大人による書き言葉では、どんな状況でも1つの疑問符で十分です。一度に複数を使用しないでください。これが二度と表示されることはありません。

GCCは、トリグラフを意図的に使用することはほとんどないため、デフォルトでは無視します。オプションを使用してそれらを有効にする-trigraphか、オプションを使用してそれらについて警告するようにコンパイラーに指示してください-Wtrigraphs

Visual C ++ 2010もデフォルトでそれらを無効にし、/Zc:trigraphsそれらを有効にすることを提案します。以前のバージョンでそれらを有効または無効にする方法については何も見つかりません。

于 2009-11-03T19:03:39.740 に答える
6

三重音字の驚きを回避する簡単な方法:「??」を分割する 2つの文字列リテラル:

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

Edit
gccには、トリグラフについて警告するオプションがあります:(これも-Wtrigraphs有効になってい-Wallます)
end edit

標準からの引用

    5.2.1.1トリグラフシーケンス
1他の処理が行われる前に、
    次の3文字のシーケンス(三重音字シーケンス13と呼ばれる))
    対応する単一の文字に置き換えられます。
           ?? =#??)] ??!|
           ??([??'^ ??>}
           ?? / \ ?? <{??-〜
    他のトリグラフシーケンスは存在しません。各 ?それは次のいずれかを開始しません
    上記のトリグラフは変更されません。
    5.1.1.2翻訳フェーズ
1翻訳の構文規則の優先順位は、次のように指定されます。
    次のフェーズ。
         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のデフォルトの動作は無視しますが、警告を出します。これははるかに正気であり、私が知る限り、VisualStudio2010が標準として採用するものです。

于 2009-11-03T19:45:12.823 に答える