

C++11を用いて日本語の文字列の入力を受け取り、それ各文字ごとに切り抜いて数を数えるプログラムを作成しているのですが、日本語を扱ったのは始めてなので知見が足りません、できればstringにrange_based_forを書けたときのようにスラスラ取りたいです。


CC BY-SA 4.0
2018-02-23T10:47:49.503
41958
2020-01-18T05:59:04.860
2020-01-18T05:59:04.860
27236
27236
question
c++ 日本語
C++で日本語文字列を切り取りたい


[`std::string` / `std::wstring` / `std::u16string` /
`std::u32string`](https://cpprefjp.github.io/reference/string/basic_string.html)
が用意されていますが、それぞれは対応する文字型（`char`など）を扱うとしか定められていません。例えば、C標準ライブラリには`stricmp`のような大文字小文字を区別しない比較が存在しますが、C++
stringにはこのような機能すらありません。  
全てはライブラリ利用者に任せられているため、マルチバイト文字になるのであればその管理もライブラリ利用者の責任です。`std::u16string`を使用することでUTF-16を扱うことができますが、その場合でも[サロゲートペア](https://ja.wikipedia.org/wiki/Unicode#%E3%82%B5%E3%83%AD%E3%82%B2%E3%83%BC%E3%83%88%E3%83%9A%E3%82%A2)の管理は利用者の責任ですし、`std::u32string`でUTF-32としたとしてもやはり[異体字セレクタ](https://ja.wikipedia.org/wiki/%E7%95%B0%E4%BD%93%E5%AD%97%E3%82%BB%E3%83%AC%E3%82%AF%E3%82%BF)などを考慮するとやはり１文字に収まることはありません。

結局のところ、何をもって「１文字」とみなすかは利用者次第であり、それに応じた処理を記述しすることになります。


CC BY-SA 3.0
2018-02-23T23:41:06.957
41967
2018-02-23T23:41:06.957
4236
41958
answer


C/C++言語規格上はリテラルを除けば「文字列」という概念は無いに等しく  
「文字コードを意味する型」の「配列」しかありません。  
また、ANSI(Shift-JIS)(別名:MBCS)系コードと、Unicode系コードで扱いが異なります。

[code]

    char     Nihongo_A[7] =  "日本語"; // char配列に日本語を入れてみた(Shif-JISコードの場合)
    wchar_t  Nihongo_W[4] = L"日本語"; // ワイド文字の配列にUnicodeの日本語を入れてみた(UTF-16等の場合)
    
[/code]

どちらも日本語を扱ってますが「１文字の概念」が文字コードによって異なるので、上記のように配列に必要な要素数が異なるわけですね。  
例外を除けばwchar_t型は１文字を意味しますので配列インデックスを指定して１文字を判定できます。

[code]

    if( Nihongo_W[1]==L'本'){
      // '本'でした
    }
    
[/code]

もちろん基本型の配列には Range-based for は使えますし、

[code]

    for( wchar_t & jc : Nihongo_W){// 
      jc = L'あ';//全部'あ'にする
    }
    
[/code]

または、その機能を持っているより高度な「文字列クラス」もあるのでそれを使用すれば良いわけですね。


CC BY-SA 3.0
2018-02-26T09:18:16.380
42020
2018-02-26T09:18:16.380
3793
41958
answer