ホームに戻る
出典 :
ワイド文字 - Wikipedia Unicode - Wikipedia char、wchar_t、char8_t、char16_t、char32_t | Microsoft Learn char16_tとchar32_t - cpprefjp C++日本語リファレンス UTF-8エンコーディングされた文字の型として`char8_t`を追加 - cpprefjp C++日本語リファレンス char16_tとchar32_tの文字・文字列リテラルを、文字コードUTF-16/32に規定 - cpprefjp C++日本語リファレンス basic_string - cpprefjp C++日本語リファレンス sリテラル - cpprefjp C++日本語リファレンス 【C++入門】string型⇔char*型に変換する方法まとめ | 侍エンジニアブログ
関連 :
stringとcharポインタの相互変換 stringstream
目次 :

C++における文字・文字列表現

C++03以前

Cでは文字型として char を用いている。これはシングルバイト(ASCIIまたはASCIIを包含するISO-8859)の1文字、およびマルチバイト文字の個々のバイトを格納する。
文字列は char [n] ( char 型の配列)で表現する。
C++では std::string が追加され、文字列をより簡便に扱えるようになった。この std::string は char 型を要素に取る動的配列である。
即ち char [n] 同様、1要素が1文字を表すとは限らない。

char を用いた場合、仮名や漢字を扱うマルチバイト環境では本来1文字であっても文字列として扱わなければならないなどの不便があり、
1文字を1つの整数値として扱えるワイド文字( wchar_t )が後に追加された。wchar_t はCにおいては他の型のエイリアスだが、C++ではキーワード(予約語)である。
wchar_t の符号化形式(文字コード)はシステムによって異なり、2023年現在、WindowsではUTF-16、LinuxやmacOSではUTF-32である。
このため、符号化形式の異なるシステムへの移植の際に問題となることがあった。

C++11以降

2000年代以降UCS/Unicodeが普及し、文字コードの標準化が進んだ。
これを受け、UTF-16およびUTF-32の1文字を格納するための char16_tchar32_t が標準C++(C++11)に導入された。
さらにC++20ではUTF-8に対応した char8_t が追加された。この char8_t は unsigned char 型と同サイズであるが、char および unsigned char とは明確に区別される。
UTF-8は1文字が可変幅(割り当てられるバイト数が文字によって異なる)であり、char8_t は char 同様、1文字を表すとは限らない。

basic_string

std::basic_string クラスは、あらゆる文字型を使用できる文字クラスである。
先述の std::string の実態は std::basic_string<char> のエイリアスであり、他の文字型をテンプレートパラメータとするエイリアスも同様に用意されている。
使用する際は、<string> のインクルードが必要となる。

リテラル

文字および文字列リテラルはプレフィックスを付与することで型を規定することができる。
また s サフィックスを付与すると配列ではなく、各文字型の basic_string オブジェクトを構築できる。
( s サフィックスは正しくは ""s 演算子関数として std::literals::string_literals 名前空間に定義されている。詳細はリンク先を参照。)
#include <string> int main() { using namespace std::literals::string_literals; //< s サフィックスの名前解決 // L プレフィックスを付与 ⇒ wchar_t のシーケンス wchar_t s[] = L"あいうえお"; // u8 プレフィックスを付与 ⇒ char8_t のシーケンス char8_t s8[] = u8"あいうえお"; // u プレフィックスを付与 ⇒ char16_t のシーケンス char16_t s16[] = u"あいうえお"; // U プレフィックスを付与 ⇒ char32_t のシーケンス char32_t s32[] = U"あいうえお"; // s サフィックスを付与 ⇒ string リテラル( const char* ではない) std::string sx = "hello"s; // s と U の併用 ⇒ u16string リテラル std::u16string sy = U"hello"s; }
u8 プレフィックスを付与するとC++17までは const char* とされていたが、C++20以降では const char8_t* として扱われる。

まとめ

文字型 サイズ
[byte]
文字列型( basic_string ) リテラル 備考
シングルバイト char 1 std::string
( std::basic_string<char> )
char c = 'a'; char ca[] = "abc"; std::string s = "abc"s; 文字コードは処理系依存
1要素が1文字を表すとは限らない
ワイド文字 wchar_t (処理系依存) std::wstring
( std::basic_string<wchar_t> )
wchar_t c = L'神'; wchar_t ca[] = L"神社"; std::wstring s = L"神社"s; 文字コードは処理系依存
UTF-8 char8_t 1 std::u8string
( std::basic_string<char8_t> )
char8_t c = u8'神'; char8_t ca[] = u8"神社"; std::u8string s = u8"神社"s; C++20以降
1要素が1文字を表すとは限らない
UTF-16 char16_t 2 std::u16string
( std::basic_string<char16_t> )
char16_t c = u'神'; char16_t ca[] = u"神社"; std::u16string s = u"神社"s; C++11以降
UTF-32 char32_t 4 std::u32string
( std::basic_string<char32_t> )
char32_t c = U'神'; char32_t ca[] = U"神社"; std::u32string s = U"神社"s; C++11以降