Programming Windows Maniacs - プログラミング ウィンドウズ マニアックス ■ ご利用に際して ■ 更新履歴 ■ お問い合わせ ■ このホームページについて  
ホーム >> 基本 >> char *文字列とwchar_t *文字列の相互変換

char *文字列とwchar_t *文字列の相互変換

  MBCS(UNICODEでない)でコンパイルする人はまだまだ多いと思います。
  MBCSでコンパイルする人ほど、char *とwchar_t *文字列の相互変換が必要になります。
  特にWindows 9x系を対応するアプリケーションを作成している方は、 MBCSにせざるを得ません。
  また、Windows NT系で作成している方でも、古いライブラリを呼び出す際には、wchar_t *からchar *に変換する機会もあると思います。

  char *文字列からwchar_t *文字列に変更するには、MultiByteToWideChar () API を使用して変換します。

  逆に、wchar_t *文字列から char *文字列に変更するには、WideCharToMultiByte () API を使用して変換します。

  以下は、char *文字列を wchar_t *文字列に変換し、wchat_t *文字列を再度 char *文字列に変更するサンプルです。
  _MBCSが定義された状態でコンパイルして実行してください。UNICODEではコンパイルできません。
  また、char *文字列を表示するためには MessageBox () API (つまりMessageBoxA () API)を、wchar_t *文字列を表示するために、MessageBoxW () APIを使用しています。

  

■■■ wide_multi プロジェクト
main.cpp

// ANSI コンパイルで、char * 文字列と wchat_t * 文字列の相互変換

// _MBCSが定義されていること
#ifndef _MBCS

#error "Cannot compile! _MBCS isn't defined."

#endif
// _MBCSが定義されていること ここまで

#include <windows.h>

int WINAPI WinMain ( HINSTANCE,
HINSTANCE,
char *,
int )
{
// MBCS → UNICODE
    const char csz[] = "あいうえ\\お\\aaa.txt";

    int nLengthForWideChar;
    nLengthForWideChar = MultiByteToWideChar ( CP_ACP,
        0,
        csz,
        -1,
        NULL,
        0 );// NULL分もサイズに含まれる

    wchar_t *pwsz = new wchar_t[ nLengthForWideChar ];
    memset ( pwsz, 0, nLengthForWideChar * sizeof ( wchar_t ) );
    MultiByteToWideChar ( CP_ACP,
        0,
        csz,
        -1,
        pwsz,
        nLengthForWideChar );

    MessageBoxW ( NULL,
        pwsz,
        L"確認",
        MB_OK );

// UNICODE → MBCS
    int nLengthForMBCS;
    nLengthForMBCS = WideCharToMultiByte ( CP_ACP,
        0,
        pwsz,
        -1,
        NULL,
        0,
        NULL,
        NULL );// NULL分もサイズに含まれる
    char *psz = new char[ nLengthForMBCS ];
    memset ( psz, 0, nLengthForMBCS * sizeof ( char ) );
    WideCharToMultiByte ( CP_ACP,
        0,
        pwsz,
        -1,
        psz,
        nLengthForMBCS,
        NULL,
        NULL );

    MessageBox ( NULL,
        psz,
        "確認",
        MB_OK );

    delete[] pwsz;

    return 0;
}

   API関数の定義について補足

  文字列を扱う WindowsのAPIは、_MBCSが定義されているか、UNICODEが定義されているかによって挙動が異なります。

  例えば、上記 MessageBox API ()ですが、_MBCS コンパイルの場合は MessageBoxA () API がコールされています。

  逆に、UNICODEが定義されている場合は、MessageBox API ()を記載しても、MessageBoxW () API がコールされます。

  この情報については、実際 下記のように winuser.h ヘッダに記載されているので、参照してみてください。

 

[winuser.hから抜粋]

WINUSERAPI
int
WINAPI
MessageBoxA(
    HWND hWnd ,
    LPCSTR lpText,
    LPCSTR lpCaption,
    UINT uType);
WINUSERAPI
int
WINAPI
MessageBoxW(
    HWND hWnd ,
    LPCWSTR lpText,
    LPCWSTR lpCaption,
    UINT uType);
#ifdef UNICODE
#define MessageBox MessageBoxW
#else
#define MessageBox MessageBoxA
#endif // !UNICODE

  ■ ご利用に際して ■ 更新履歴 ■ お問い合わせ ■ このホームページについて Copyright © 2014 A.Morita