名前空間
変種
操作

文字列リテラル

提供: cppreference.com
< c‎ | language

指定された文字配列型の無名オブジェクトをその場で構築します。 文字列をソースコード中に埋め込む必要があるときに使用されます。

目次

[編集] 構文

" s-char-sequence " (1)
u8 " s-char-sequence " (2) (C11以上)
u " s-char-sequence " (3) (C11以上)
U " s-char-sequence " (4) (C11以上)
L " s-char-sequence " (5)

ただし

s-char-sequence - 0個以上の文字。 各文字は、ソース文字集合のマルチバイト文字 ("\、および改行を除きます)、またはエスケープシーケンスに掲載されている文字エスケープ、16進エスケープ、8進エスケープまたはユニバーサル文字名 (C99以上)の、いずれかです。


1) 文字列リテラル。 リテラルの型は char[N] です。 ただし N は実行ナローエンコーディングのコードユニットにおける文字列のサイズです (終端のヌル文字を含みます)。 配列内の各 char 要素は実行文字集合を用いて s-char-sequence 内の次の文字から初期化されます。
2) UTF-8 文字列リテラル。 リテラルの型は char[N] です。 ただし N は UTF-8 コードユニットにおける文字列のサイズです (終端のヌル文字を含みます)。 配列内の各 char 要素は UTF-8 エンコーディングを用いて s-char-sequence 内の次のマルチバイト文字から初期化されます。
3) 16ビットワイド文字列リテラル。 リテラルの型は char16_t[N] です。 ただし N は処理系定義の16ビットエンコーディング (一般的には UTF-16) のコードユニットにおける文字列のサイズです (終端のヌル文字を含みます)。 配列内の各 char16_t 要素は処理系定義のロケールで mbrtoc16 を実行したかのように初期化されます。
4) 32ビットワイド文字列リテラル。 リテラルの型は char32_t[N] です。 ただし N は処理系定義の32ビットエンコーディング (一般的には UTF-32) のコードユニットにおける文字列のサイズです (終端のヌル文字を含みます)。 配列内の各 char32_t 要素は処理系定義のロケールで mbrtoc32 を実行したかのように初期化されます。
5) ワイド文字列リテラル。 リテラルの型は wchar_t[N] です。 ただし N は実行ワイドエンコーディングのコードユニットにおける文字列のサイズです (終端のヌル文字を含みます)。 配列内の各 wchar_t 要素は処理系定義のロケールで mbstowcs を実行したかのように初期化されます。

[編集] 説明

まず、翻訳フェーズ6 (マクロ展開の後) で、隣接する文字列リテラル (つまり、ホワイトスペースのみで区切られた文字列リテラル) が連結されます。

ナロー文字列リテラル2つまたはワイド文字列リテラル2つのみが連結できます。

(C99未満)

一方のリテラルが接頭辞を持たない場合、結果の文字列は接頭辞付きのリテラルによって指定された幅/エンコーディングを持ちます。 2つの文字列リテラルが異なるエンコーディング接頭辞を持つ場合、連結は処理系定義です。

L"Δx = %" PRId16 // フェーズ4で、 PRId16 は "d" に展開されます。
                 // フェーズ6で、 L"Δx = %" と "d" が L"Δx = %d" を形成します。
(C99以上)

その後、翻訳フェーズ7で、各文字列リテラルに終端のヌル文字が追加され、各リテラルが、、文字列リテラルの内容およびヌル終端1個を含むのにちょうど十分な長さの、静的記憶域期間を持つ無名配列を初期化します。

char* p = "\x12" "3"; // {'\x12', '3', '\0'} を保持する static char[3] 配列を作成し、
                      // その配列の最初の要素を指すように p を初期化します。

文字列リテラルは変更不可能です (実際、 .rodata のような読み込み専用メモリに配置されることもあります)。 文字列リテラルによって形成された静的配列をプログラムが変更しようと試みた場合、動作は未定義です。

char* p = "Hello";
p[1] = 'M'; // 未定義動作。
char a[] = "Hello";
a[1] = 'M'; // OK、 a は文字列リテラルではありません。

同一の文字列リテラルがメモリ内の同じ位置を参照することは要求も禁止もされていません。 また、オーバーラップする文字列リテラルまたは別の文字列リテラルの部分文字列である文字列リテラルが結合されることもあります。

"def" == 3+"abcdef"; // 1 になることも 0 になることもあります (処理系定義)。

[編集] ノート

文字列リテラルが1個の文字列であるとは限りません。 文字列リテラルが途中にヌル文字を持つ場合、それは複数の文字列を含む配列を表します。

char* p = "abc\0def"; // strlen(p) == 3 ですが、配列のサイズは 8 です。

文字列リテラル内で16進エスケープに有効な16進数字が続く場合は、無効なエスケープシーケンスとしてコンパイルに失敗しますが、ワークアラウンドとして文字列の連結が使用できます。

//char* p = "\xfff"; // エラー、16進エスケープシーケンスが範囲外です。
char* p = "\xff""f"; // OK、リテラルは char[3] で、 {'\xff', 'f', '\0'} を保持します。

文字列リテラルは配列を初期化するために使用することもでき、配列のサイズが文字列リテラルのサイズより1小さい場合、ヌル終端は無視されます。

char a1[] = "abc"; // a1 は char[4] で、 {'a', 'b', 'c', '\0'} を保持します。
char a2[4] = "abc"; // a2 は char[4] で、 {'a', 'b', 'c', '\0'} を保持します。
char a3[3] = "abc"; // a3 は char[3] で、 {'a', 'b', 'c'} を保持します。

文字列リテラル (1) およびワイド文字列リテラル (5) のエンコーディングは処理系定義です。 例えば、 gcc ではコマンドラインオプション -fexec-charset および -fwide-exec-charset で指定できます。

[編集]

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <uchar.h>
#include <locale.h>
int main(void)
{
    char s1[] = "a猫🍌"; // または "a\u732B\U0001F34C"
    char s2[] = u8"a猫🍌";
    char16_t s3[] = u"a猫🍌";
    char32_t s4[] = U"a猫🍌";
    wchar_t s5[] = L"a猫🍌";
 
    setlocale(LC_ALL, "en_US.utf8");
    printf("  \"%s\" is a char[%zu] holding { ", s1, sizeof s1 / sizeof *s1);
    for(size_t n = 0; n < sizeof s1 / sizeof *s1; ++n) 
        printf("%#x ", +(unsigned char)s1[n]); 
    puts(" }");
    printf("u8\"%s\" is a char[%zu] holding { ", s2, sizeof s2 / sizeof *s2);
    for(size_t n = 0; n < sizeof s2 / sizeof *s2; ++n) 
       printf("%#x ", +(unsigned char)s2[n]); 
    puts(" }");
    printf(" u\"a猫🍌\" is a char16_t[%zu] holding { ", sizeof s3 / sizeof *s3);
    for(size_t n = 0; n < sizeof s3 / sizeof *s3; ++n) 
       printf("%#x ", s3[n]); 
    puts(" }");
    printf(" U\"a猫🍌\" is a char32_t[%zu] holding { ", sizeof s4 / sizeof *s4);
    for(size_t n = 0; n < sizeof s4 / sizeof *s4; ++n) 
       printf("%#x ", s4[n]); 
    puts(" }");
    printf(" L\"%ls\" is a wchar_t[%zu] holding { ", s5, sizeof s5 / sizeof *s5);
    for(size_t n = 0; n < sizeof s5 / sizeof *s5; ++n) 
       printf("%#x ", (unsigned)s5[n]); 
    puts(" }");
}

出力例:

"a猫🍌" is a char[9] holding { 0x61 0xe7 0x8c 0xab 0xf0 0x9f 0x8d 0x8c 0  }
u8"a猫🍌" is a char[9] holding { 0x61 0xe7 0x8c 0xab 0xf0 0x9f 0x8d 0x8c 0  }
 u"a猫🍌" is a char16_t[5] holding { 0x61 0x732b 0xd83c 0xdf4c 0  }
 U"a猫🍌" is a char32_t[4] holding { 0x61 0x732b 0x1f34c 0  }
 L"a猫🍌" is a wchar_t[4] holding { 0x61 0x732b 0x1f34c 0  }

[編集] 参考文献

  • C11 standard (ISO/IEC 9899:2011):
  • 6.4.5 String literals (p: 70-72)
  • C99 standard (ISO/IEC 9899:1999):
  • 6.4.5 String literals (p: 62-63)
  • C89/C90 standard (ISO/IEC 9899:1990):
  • 3.1.4 String literals

[編集] 関連項目

文字列リテラルC++リファレンス