none
Cstringの文字列のコードの取得 RRS feed

  • 質問

  • 基本的な質問になってしまうのですが、

    CString型の文字列の個別の文字の文字コードを取得したいのですが、どのように取得するのでしょう

    CString a=_T("あいうえおabcd");

    とした場合、

    a[0] = 0x82a0;//あ
    a[1] = 0x82a2;//い
    a[5] = 0x61;    //a

    となると思うのですが、このコードをとるにはどうすれば良いでしょう

    すいません。VC++2010です。
    コードも修正しました

    2011年7月19日 10:01

回答

  • コードページではなくて、各文字の文字コードを取得したいのですよね?

     

    CStringはプロジェクトの設定によってCStringAかCStringWのどちらかになります。

    どちらもCStringTテンプレートのインスタンス化です。

    ドキュメントはCStringTまたはその継承元のCSimpleStringTクラステンプレートを参照して下さい。

    CSimpleStringTに以下のメンバ関数があります:

    • GetAt()
    • operator[]

     

    CStringWはUTF-16LEで各文字を保存し、1文字バッファあたり1文字が格納されます。

    そのため文字コードを取得するのは上記のメンバ関数を使えば単純でしょう。

     

    CStringAは環境や設定によって保持する文字のコードページが変わります。

    また、そのコードページに応じて異なる処理をしなければ文字コードは取得できないでしょう。

     

    いちろうさんは、どのような環境・設定において、どのコードページに基づいた文字コードを取得したいのでしょうか?

    • 回答としてマーク いちろう 2011年7月20日 16:27
    2011年7月19日 10:25
  • >a[0] = 0x82a0;//あ
    >a[1] = 0x82a2;//い
    >a[5] = 0x61;    //a
    Shift-JISかな?
    >となると思うのですが、
    Projectのcharacter setの設定が、
    MBCSになっている場合は、そうなりますね。
    character setの設定はdefaultでUnicodeになっていますので、
    設定を変更していない場合、UTF16からShift-JISへの変換が必要です。
    WideCharToMultiByte APIを利用します。
    あと、UTF-16は1文字=2byte(1 WCHAR)とは限りませんよ。
    Surrogate Pairに該当する文字は、4byte(2 WCHAR)になります。
    • 回答としてマーク いちろう 2011年7月20日 16:26
    2011年7月19日 10:45
  • 質問が中途半端です。たぶん質問者の方が問題を理解していないからでしょう。

    「コードをとる」とはどういう意味で質問されましたか?

    1) メモリー上に a[0] = 0x80a0 となるように格納し、その値を読み出したい。

    cbr600rrさんとkozzさんが少し触れられていますが、プロジェクトの設定にMBCSとUNICODEがあります。デフォルトではUNICODEですが、MBCSにした場合、意図通りになります。

    そのほか、

    CStringA a = "あいうえおabcd";

    と書いても実現できます。こちらはプロジェクトの設定に影響されません。

    MBCSにした場合、文字はchar型、1byte単位になります。 0x82a0 は2バイトなので、 a[1] = 0x82a2 とはなりません。a[0] = 0x82、a[1] = 0xa0、a[2] = 0x82、a[3] = 0xa2

    それとは別に、コンストラクタの使い方として

    CString a( _T("あいうえおabcd") );

    という書き方をお勧めします。

    2) メモリー上に a[0] = 0x3042、a[1] = 0x3044とUnicodeで格納し、その値を文字コード変換したい。

    kozzさんも触れられていますが、WideCharToMultiByteなどで文字コード変換できます。

    質問文からはどちらの意味でも解釈できますが…勝手な予想としては、質問者の方はそもそも文字コードの概念を知らないかな、と。その場合、きっと前者の意味ということになりますが、過去に質問された内容との兼ね合いからすると、C#とのインターフェースを見直す必要も出てきます。

    質問の際、期待した結果とどう違うのか、実際にはどうなったかを含めると、何がしたいのか、何が間違っているのかが伝わりやすくなると思います。

    • 回答としてマーク いちろう 2011年7月20日 16:26
    2011年7月19日 13:43

すべての返信

  • コードページではなくて、各文字の文字コードを取得したいのですよね?

     

    CStringはプロジェクトの設定によってCStringAかCStringWのどちらかになります。

    どちらもCStringTテンプレートのインスタンス化です。

    ドキュメントはCStringTまたはその継承元のCSimpleStringTクラステンプレートを参照して下さい。

    CSimpleStringTに以下のメンバ関数があります:

    • GetAt()
    • operator[]

     

    CStringWはUTF-16LEで各文字を保存し、1文字バッファあたり1文字が格納されます。

    そのため文字コードを取得するのは上記のメンバ関数を使えば単純でしょう。

     

    CStringAは環境や設定によって保持する文字のコードページが変わります。

    また、そのコードページに応じて異なる処理をしなければ文字コードは取得できないでしょう。

     

    いちろうさんは、どのような環境・設定において、どのコードページに基づいた文字コードを取得したいのでしょうか?

    • 回答としてマーク いちろう 2011年7月20日 16:27
    2011年7月19日 10:25
  • >a[0] = 0x82a0;//あ
    >a[1] = 0x82a2;//い
    >a[5] = 0x61;    //a
    Shift-JISかな?
    >となると思うのですが、
    Projectのcharacter setの設定が、
    MBCSになっている場合は、そうなりますね。
    character setの設定はdefaultでUnicodeになっていますので、
    設定を変更していない場合、UTF16からShift-JISへの変換が必要です。
    WideCharToMultiByte APIを利用します。
    あと、UTF-16は1文字=2byte(1 WCHAR)とは限りませんよ。
    Surrogate Pairに該当する文字は、4byte(2 WCHAR)になります。
    • 回答としてマーク いちろう 2011年7月20日 16:26
    2011年7月19日 10:45
  • 質問が中途半端です。たぶん質問者の方が問題を理解していないからでしょう。

    「コードをとる」とはどういう意味で質問されましたか?

    1) メモリー上に a[0] = 0x80a0 となるように格納し、その値を読み出したい。

    cbr600rrさんとkozzさんが少し触れられていますが、プロジェクトの設定にMBCSとUNICODEがあります。デフォルトではUNICODEですが、MBCSにした場合、意図通りになります。

    そのほか、

    CStringA a = "あいうえおabcd";

    と書いても実現できます。こちらはプロジェクトの設定に影響されません。

    MBCSにした場合、文字はchar型、1byte単位になります。 0x82a0 は2バイトなので、 a[1] = 0x82a2 とはなりません。a[0] = 0x82、a[1] = 0xa0、a[2] = 0x82、a[3] = 0xa2

    それとは別に、コンストラクタの使い方として

    CString a( _T("あいうえおabcd") );

    という書き方をお勧めします。

    2) メモリー上に a[0] = 0x3042、a[1] = 0x3044とUnicodeで格納し、その値を文字コード変換したい。

    kozzさんも触れられていますが、WideCharToMultiByteなどで文字コード変換できます。

    質問文からはどちらの意味でも解釈できますが…勝手な予想としては、質問者の方はそもそも文字コードの概念を知らないかな、と。その場合、きっと前者の意味ということになりますが、過去に質問された内容との兼ね合いからすると、C#とのインターフェースを見直す必要も出てきます。

    質問の際、期待した結果とどう違うのか、実際にはどうなったかを含めると、何がしたいのか、何が間違っているのかが伝わりやすくなると思います。

    • 回答としてマーク いちろう 2011年7月20日 16:26
    2011年7月19日 13:43
  • ありがとうございます。

    Shift-JISで文字コードを取りたいと書くのが抜けていました
    プロジェクト自体はUNICODEを使用するようにさくせいしていて、文字列はUNICODEでやりとりされます

    特定の文字だけS-JISで取得したかったのがわかりませんでした。
    WideCharToMultiByte で、うまく変換出来ました。

    2011年7月20日 16:26
  • WideCharToMultiByte()でもいいですが、文字列変換マクロを使うと変換も簡単にできます。

    CStringはTCHAR型で、char型のSHIFT_JISに変換したい場合、CT2Aとなります。これのいいところは、WideCharToMultiByte()の場合、あくまでCW2Aであり、TCHARからの変換を行っているわけではありません。あまりしないかもしれませんがプロジェクトの設定をMBCSに変えた際に、TCHARはchar相当になり、WideCharToMultiByte()では処理が矛盾してしまいます。そのような場合でもCT2AはCA2Aとなり正しく無変換の動作をします。

    2011年7月20日 23:02