web-dev-qa-db-ja.com

16進エスケープを文字列リテラルに適切に追加する方法は?

Cに文字列がある場合、内部に直接16進コードを追加できます。

char str[] = "abcde"; // 'a', 'b', 'c', 'd', 'e', 0x00
char str2[] = "abc\x12\x34"; // 'a', 'b', 'c', 0x12, 0x34, 0x00

どちらの例もメモリに6バイトがあります。 16進エントリ​​の後に値[a-fA-F0-9]を追加する場合、問題が存在します。

//I want: 'a', 'b', 'c', 0x12, 'e', 0x00
//Error, hex is too big because last e is treated as part of hex thus becoming 0x12e
char problem[] = "abc\x12e";

考えられる解決策は、定義後に置き換えることです。

//This will work, bad idea
char solution[6] = "abcde";
solution[3] = 0x12;

これは機能しますが、constとして指定すると失敗します。

//This will not work
const char solution[6] = "abcde";
solution[3] = 0x12; //Compilation error!

エラーを引き起こさずに\x12の後にeを適切に挿入する方法は?


なぜ私が尋ねているのですか? TF-8文字列を定数として構築する場合、ASCIIテーブルが保持できるよりも大きい場合は、文字の16進値を使用する必要があります。

44
tilz0R

3桁の8進数を使用します。

char problem[] = "abc\022e";

または、文字列を分割します:

char problem[] = "abc\x12" "e";

これらが機能する理由:

  • 16進エスケープとは異なり、標準では8進エスケープの最大量として3桁を定義しています。

    6.4.4.4文字定数

    ...

    octal-escape-sequence:
        \ octal-digit
        \ octal-digit octal-digit
        \ octal-digit octal-digit octal-digit
    

    ...

    hexadecimal-escape-sequence:
        \x hexadecimal-digit
        hexadecimal-escape-sequence hexadecimal-digit
    
  • 文字列リテラルの連結は、リテラルエスケープ文字の変換よりも後の翻訳段階として定義されます。

    5.1.1.2翻訳フェーズ

    ...

    1. 文字定数および文字列リテラルの各ソース文字セットメンバーとエスケープシーケンスは、実行文字セットの対応するメンバーに変換されます。対応するメンバーがない場合、ヌル(ワイド)文字以外の実装定義のメンバーに変換されます。 8)

    2. 隣接する文字列リテラルトークンは連結されます。

53
user694733

文字列リテラルはコンパイルプロセスの早い段階で連結されますが、エスケープ文字変換の後にafterを使用できるため、次のように使用できます。

char problem[] = "abc\x12" "e";

ただし、読みやすいように完全に分離することもできます。

char problem[] = "abc" "\x12" "e";

私たちの中の言語弁護士にとって、これはC11 5.1.1.2 Translation phases(私の強調):

  1. 各ソース文字セットのメンバーとエスケープシーケンス文字定数と文字列リテラルは、実行文字セットの対応するメンバーに変換されます。対応するメンバーがない場合、ヌル(ワイド)文字以外の実装定義のメンバーに変換されます。

  2. 隣接する文字列リテラルトークンは連結されます。

19
paxdiablo

なぜ私が尋ねているのですか? UTF-8文字列を定数として作成する場合、ASCIIテーブルが保持できる文字よりも大きい文字の16進値を使用する必要があります。

うーん、ダメ。 する必要があるではありません。 C11の時点では、文字列定数の前にu8を付けることができます。これは、文字リテラルがUTF-8であることをコンパイラーに伝えます。

char solution[] = u8"no need to use hex-codes á駵";

(ちなみに、同じことがC++ 11でもサポートされています)

4
Damon