読者です 読者をやめる 読者になる 読者になる

コンパイラかく語りき

文系新卒プログラマーのメモ

cpp 日本語文字列についてメモ

言語100本ノックに挑んだら、いきなりつまづいてしまった

 

www.cl.ecei.tohoku.ac.jp

 

"パトカー"の出力ができていないさそう。なにやら文字化けが表示される。ひょっとしたら文字コード周りの問題か…?

 

マルチバイト文字列とワイド文字列

そもそも、cppの文字列にはマルチバイト文字列とワイド文字列が存在するらしい。

 

C/C++での日本語文字列の扱い、どうすればよいか - minus9d's diary

 

マルチバイトとか文字コードとか…あまり得意ではない…。ので、軽く調べてみた。

 

・マルチバイトとは従来のchar型みたいに1Byte文字と2Byte文字を分けて考える概念のこと
ユニコードとはWCHAR型の様に日本語や中国語やアルファベットや数値などを区別無く扱う概念のこと

 

charとUnicodeとワイド文字をごっちゃにしないために

 

なんてわかりやすい…。

 

ワイド文字列にはwstring

 

上記の記事では、char[] strw = L"こんにちは" と、文字型の配列を利用している。個人的にはstringを使っていきたいので、もうちょっと調べる。

 

どうやらwstringというものがあるらしく、これを使えばワイド文字列を扱うことができる。

 

wstring - C++ Reference

 

しかも、使えるメソッドはstringと同じ。

 

つまり、string にせよ、wstring にせよ、そこに含まれる機能はどちらも std::basic_string が提供しているものですから、 まったく同じ使い方ができます。

 

Programming Place Plus C++編【標準ライブラリ】 第2章 string

 

それと、Lや_Tのような標準マクロを使ってリテラルを宣言できます。

 

ちなみにユニコード設定でもマルチバイト設定でも両方で通用するようにプログラミングするには

char * text = "文字列";
とか
WCHAR * text = L"文字列";
という書き方ではどちらか片方に限定した書き方なのでダメです。
TCHAR * text = _T("文字列");
と書くのが正解です。

 

なんて分かりやすい解説。

 

wstringを使うときはLが必要なときがあります

 

普通にstringで良かった

ここまで書いておいてアレですが、wstringをごにょごにょといじっていたところ、stringで良いことに気づいた

 

string型の変数に代入した"パタトクカシーー"自体は出力されていた。問題は、添字でのアクセスができていないことだった。

 

gistd4ca5fabb1497b7aac2d2be3b760559e

 

自分の環境ではUTF-8がデフォルトだったらしく、文字コードについて悩む必要はそもそもありませんでした。コンパイラやcppのバージョンにも寄るんでしょうけど。

 

そもそも、今時は多バイトunicodeが標準な気がするので(要調査)、2バイトunicodeのワイド文字列は不適切かもしれませんね。すくなくとも、100本ノックをこなすレベルでは、必要なさそうでした。

 

添字アクセスするには…?

ICUというライブラリを使えば、以下のように書けるようです。

 

gist7003eeb1a669bd5568299006b58cfd6f

 

Unicode string indexing in C++ - Stack Overflow