wchar_t の文字列を char の文字列に変換する [C++Builder]

Win32API で取得する各種の情報は wchar_t * 型の文字列で返ってくるので char * 型に変換したい事があります。その変換方法です。

UnicodeString を使う方法とwcstombs_s を使う方法を記載します。どちらを使っても変換できます。UnicodeString を使う方が簡単です。

UnicodeString を使って変換する

wchar_t * の文字列を UnicodeString に入れ、AnsiString にキャストし、c_str() します。

    wchar_t src[128] = L"abcあいうdefえお";
    char dest[128] = "";

    // wchar_t → char に変換する
    strncpy(dest, AnsiString(UnicodeString(src)).c_str(), sizeof(dest));
    *(dest + sizeof(dest) - 1) = '\0';

    printf("%s", dest);  //「abcあいうdefえお」が表示される

wcstombs_s を使って変換する

setlocal(LC_CTYPE, “jpn”) でロケールを設定し、wcstombs_s で変換します。

    wchar_t src[128] = L"abcあいうdefえお";
    char dest[128] = "";

    setlocale(LC_CTYPE, "jpn");

    // wchar_t → char に変換する
    size_t returnValue = 0;
    errno_t err = wcstombs_s(&returnValue, dest, destSize, src, _TRUNCATE);
    if (err != 0) {
        // 変換に失敗した。
        return;
    }

    printf("%s", dest);  //「abcあいうdefえお」が表示される

wcstombs_s が失敗する場合

上手くいかなかったケースも記載しておきます。

wcstombs_s() の変換に失敗して EILSEQ が返る

wcstombs_s で変換する場合には、setlocale(LC_CTYP, “jpn”); が必要です。setlocale(LC_CTYP, “jpn”);を忘れるとエラーになってしまい、dest に何も格納されません。

    wchar_t src[128] = L"abcあいうdefえお";
    char dest[128] = "";

    // setlocale(LC_CTYPE, "jpn");

    size_t returnValue = 0;
    errno_t err = wcstombs_s(&returnValue, dest, destSize, src, _TRUNCATE);
    if (err == EILSEQ) {
        // setlocale(LC_CTYPE,"jpn") を忘れると EILSEQ になります。
        // returnValue は 0, err は EILSEQ, dest は "" のままです。
    }

マルチバイト文字に変換できないワイド文字が検出されて失敗します。returnValue が 0 になり、EILSEQ が返ってきます。

wcstombs_s が見つからない

[bcc64 エラー] Unit1.cpp(28): use of undeclared identifier 'wcstombs_s'

ターゲット プラットフォームを『Windows 64 ビット(モダン)』にすると通ります。『Windows 32 ビット』『Windows 64 ビット』は エラーになります。

参考

コメント