3流プログラマのメモ書き

元開発職→社内SE→派遣で営業支援の三流プログラマのIT技術メモ書き。 このメモが忘れっぽい自分とググってきた技術者の役に立ってくれれば幸いです。(jehupc.exblog.jpから移転中)

(VC++)Windows環境でのcharの文字コード(マルチバイトとユニコード)で混乱

Visual Studio 2008 では(VS 2005でも同じ) MFC の関数や、Win32API 関数で引数に文字列を渡すとき _T("文字列") と書かないといけないようです。

たしか、Visual C++ 6.0 のときはいらなかったよなーと思ってたので、ちょっと調べてみました。

ちなみに、_T("")をつけないと下記のようなコンパイルエラーとなったりします。

エラー1error C2664: 'ShellExecuteW' : 2 番目の引数を 'const char [5]' から 'LPCWSTR' に変換できません。(新しい機能 ; ヘルプを参照)

詳しくは_T("")マクロだのL""マクロだのLPCTSTRだのの世界一詳しい解説で説明されてます。

要は、Visual Studio 2005 から文字列がマルチバイト(MBCS)からユニコード(wchar_t)に変わったためみたいですね。

(具体的にはプロジェクトの 構成プロパティ → 全般 で 文字セット が Unicode 文字セットを使用する になってます。)

Unicode にすると、日本語のような2バイト文字でも、1文字としてカウントできるようです。(マルチバイトで日本語を扱おうとすると、1文字が2バイトになるため、扱いにくい。)

マルチバイトについては、ウィキペディア:マルチバイト文字の「ワイド文字との対比」が参考になります。

で、_T("")マクロを使うことでユニコード設定とマルチバイト設定の差異を解消し、ユニコード設定ならL"文字列"として展開し、 マルチバイト設定なら従来どおり"文字列"とLは付加せずに展開するようです。(ちなみに、_T は _TEXT と同じらしいです。)

あと、MSDNとか見てると文字列の型で LPCSTR とか、LPCWSTR とか出てくるんですが、その意味は結局下記のようだそうでです。

LPCSTR   中身はconst CHAR * 文字列ポインタ

LPCWSTR  中身はconst WCHAR * ユニコードの文字列ポインタ

LPCTSTR  中身はconst TCHAR * 型の変化に適応する文字列ポインタ(?)

詳しくは、紛らわしいぞ!LPCTSTR、LPTSTR、LPSTR、LPCSTRは全部意味が違う!や、TCHARとかLPCTSTR、LPTSTRって何???でまとめられてます。

当然各種文字列関数も、マルチバイト用、ユニコード用、両方対応版とあるので、注意が必要ですね。

安全なのは両方対応版でしょうか。

文字列関数についても、たくさんある文字列比較用関数から必要なものを見つけるでまとめられてます。

各種文字列関数の一覧はMSDN:文字列操作のリファレンスで載せられてます。

やはり、文字列をchar型配列して扱うC/C++は簡単な文字列操作も厄介ですね。

ブランクがあると厳しいです。

追記:

printf等文字列関数も、マルチバイト用(sprintf)、Unicode用(swprintf) 等あるので、両対応用(_stprintf)にすると便利だと思います。

参考:

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