トップ回答者
WideCharToMultiByteの使い方

質問
-
お世話になります。
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;
}
回答
-
ササッとコードを書いてみた。
Samplechar* 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:tringを使えばいいですね。
すべての返信
-
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_s、wcscpy_s、_mbscpy_s -
ササッとコードを書いてみた。
Samplechar* 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:tringを使えばいいですね。