none
WideCharToMultiByteの使い方 RRS feed

  • 質問

  • お世話になります。

    UNICODE文字列からShiftーJIS文字列に変換するのにWideCharToMultiByte関数を使っているのですが、"gaf04101.exe"のようなアスキー文字?だと変換エラします。漢字もしくは数字だけだと変換します。関数は下記なのですが、どこがおかしいのでしょうか?御教授御願いできるでしょうか?

     

    char* A::cstrTochar2(CString inCstr)
    {
     /*
     inCstr=変換元文字列
     */
     size_t rt;
     int nLen;
     char *me_node;
     wchar_t *a;
     a=(wchar_t*)malloc(inCstr.GetLength()*2+1);
     wcscpy_s(a,inCstr.GetLength()*2+1,inCstr.GetString());
     nLen = ::WideCharToMultiByte(CP_THREAD_ACP,0,a,-1,NULL,0,NULL,NULL);
     if(nLen!=0)
     {
      me_node=(char*)malloc(nLen);
      nLen = ::WideCharToMultiByte(CP_THREAD_ACP,0,a,wcslen(a)+1,me_node,nLen*2,NULL,NULL);
     }
     

     return me_node;
    }

    2007年9月6日 6:46

回答

  • ササッとコードを書いてみた。

    Sample
    char* CStringToAsnsi(const CString source)
    {
        char* result = NULL;
    #ifdef UNICODE
        const int len = ::WideCharToMultiByte(CP_THREAD_ACP,
                                          0, source, -1, NULL, 0, NULL, NULL);
        if (len > 0)
        {
            result = new char[len];
            if (!::WideCharToMultiByte(CP_THREAD_ACP,
                                       0, source, -1, result, len, NULL, NULL))
            {
                delete[] result;
                result = NULL;
            }
        }
    #else
        result = new char[source.GetLength() + 1];
        strcpy_s(result, source.GetLength() + 1, source);
    #endif
        return result;
    }


    メモリ管理が面倒な場合はstd:Tongue Tiedtringを使えばいいですね。

    2007年9月6日 7:56

すべての返信

  • nLen = ::WideCharToMultiByte(CP_THREAD_ACP,0,a,wcslen(a)+1,me_node,nLen*2,NULL,NULL);

    は * 2しなくても良いのでは?

    それと、変数aはいつfreeされるんでしょうかね?
    いちいちwchar_t*型変数を使わなくとも、WideCharToMultiByteでそのままinCstrを指定すればよいのでは?


    a=(wchar_t*)malloc(inCstr.GetLength()*2+1);

    1ではなく2ですね。考え方としては

    a = (wchar_t*)malloc((inCstr.GetLength() + 1) * 2);


    ということです。
    (L'\0'は2バイト)

    もっとも、C++ですのでnewを使って

    a = new wchar_t[inCstr.GetLength() + 1];

    としたほうが簡潔でしょうけど。

    追記

    wcscpy_s(a,inCstr.GetLength()*2+1,inCstr.GetString());

    第二引数は文字数ですので、まずいですね。
    (そこが違っていると、何のためのxxx_sなのかってことに。)

    MSDN
    strcpy_swcscpy_s、_mbscpy_s

    2007年9月6日 7:35
  • ササッとコードを書いてみた。

    Sample
    char* CStringToAsnsi(const CString source)
    {
        char* result = NULL;
    #ifdef UNICODE
        const int len = ::WideCharToMultiByte(CP_THREAD_ACP,
                                          0, source, -1, NULL, 0, NULL, NULL);
        if (len > 0)
        {
            result = new char[len];
            if (!::WideCharToMultiByte(CP_THREAD_ACP,
                                       0, source, -1, result, len, NULL, NULL))
            {
                delete[] result;
                result = NULL;
            }
        }
    #else
        result = new char[source.GetLength() + 1];
        strcpy_s(result, source.GetLength() + 1, source);
    #endif
        return result;
    }


    メモリ管理が面倒な場合はstd:Tongue Tiedtringを使えばいいですね。

    2007年9月6日 7:56
  •  

    CW2A(), W2A() の類を使うのでは駄目なのでしょうか?

     

    2007年9月6日 8:10
  • 蒼の洞窟さんありがとうございました。

    動作不良の関数には、不良コードが一杯あるのですね・・・(わかってはいるが・・・・)

    記載いただいた関数で無事動作しました。ありがとうございました。

    2007年9月6日 23:17
  • 渋木さん、わざわざの返信ありがとうございます。簡単に言いますとCW2A()の使い方が良く判らなかったので、Wide関数を使いました。MSDNも良くわからず、本フォーラムに投稿しました。

    2007年9月6日 23:19