- EncodeToUTF8
- Posted by Jonas Nordstrom on December 16th, 2003
I want to encode a MBCS CString to an UTF-8 string.
I wrote a method like this:
bool EncodeToUTF8(const CString& sStr, CString& sOutStr)
{
CString tmpStr;
LPWSTR lpszW;
LPTSTR lpStr;
LPSTR lpUtf8;
int iMaxLen, iLen, iRet;
sOutStr.Empty();
iMaxLen = sStr.GetLength();
tmpStr = sStr;
lpStr = tmpStr.GetBuffer(tmpStr.GetLength());
iLen = MultiByteToWideChar(CP_ACP, 0, lpStr, -1, NULL, NULL);
lpszW = new WCHAR[iLen];
iRet = MultiByteToWideChar(CP_ACP, 0, lpStr, -1, lpszW, iLen);
tmpStr.ReleaseBuffer();
if (!iRet)
{
delete lpszW;
return false;
}
iLen = WideCharToMultiByte(CP_UTF8, 0, lpszW, -1, NULL, NULL, NULL,
NULL);
lpUtf8 = new TCHAR[iLen];
iRet = WideCharToMultiByte(CP_UTF8, 0, lpszW, -1, lpUtf8, iLen, NULL,
NULL);
delete lpszW;
if (!iRet)
{
delete lpUtf8;
return false;
}
sOutStr = lpUtf8;
delete lpUtf8;
return true;
}
Now, something might be wrong with this method, it might leak memory
or something like that, because the exe-file crashes after a while and
the UTF-8-encoding is the only new thing added.
I call the metod like this:
CString sTmpUserUTF8, sUserNo;
....
if (!EncodeToUTF8(sUserNo, sTmpUserUTF8))
{
return FALSE;
}
string sTmpUser = (string) sTmpUserUTF8;
Are there any obvious errors?
Jonas Nordstrom
- Posted by Boris Dynin on December 18th, 2003
I can see 3 possible problems:
#1. You don't check if return value of MultiByteToWideChar() and
WideCharToMultiByte() == 0: indication of an error.
#2. When you allocate an array of objects:
MyObj* obj = new MyObj[length];
you should free it like this:
delete[] obj;
rather than
delete obj;
This would definitely be a problem for *real* class objects. However, you
only call 'new' for WCHARs and TCHARs; I'm not sure if it'll cause any
leaks.
#3. You should never allocate unintialized variables/memory because it's
difficult to reproduce any possible problems in that case: variable/memory
contents is random and the problem could happen randomly.
For example, instead of
int iMaxLen;
you should declare it
int iMaxLen = 0;
Instead of allocating memory like this:
lpszW = new WCHAR[iLen];
you should do it like this:
lpszW = new WCHAR[iLen];
memset(lpszW,0,sizeof(WCHAR)*iLen);
Hope this helps,
Boris
"Jonas Nordstrom" <windydaggers@hotmail.com> wrote in message
news:8051cf6f.0312160648.bebc109@posting.google.co m...
- Posted by Boris Dynin on December 18th, 2003
Actually,
You do check API return values in some cases: so, I'm not quite correct
here.
However, you should check return values of ALL calls to API functions.
For example, instead of:
lpStr = tmpStr.GetBuffer(tmpStr.GetLength());
iLen = MultiByteToWideChar(CP_ACP, 0, lpStr, -1, NULL, NULL);
lpszW = new WCHAR[iLen];
iRet = MultiByteToWideChar(CP_ACP, 0, lpStr, -1, lpszW, iLen);
tmpStr.ReleaseBuffer();
if (!iRet)
{
delete lpszW;
return false;
}
it should be coded like this:
lpStr = tmpStr.GetBuffer(tmpStr.GetLength());
iLen = MultiByteToWideChar(CP_ACP, 0, lpStr, -1, NULL, NULL);
if (!iLen) // Added statement
{
return false;
}
lpszW = new WCHAR[iLen];
iRet = MultiByteToWideChar(CP_ACP, 0, lpStr, -1, lpszW, iLen);
tmpStr.ReleaseBuffer();
if (!iRet)
{
delete lpszW;
return false;
}
Boris
"Boris Dynin" <spam@noplease.com> wrote in message
news:CfgEb.3441$XF6.79833@typhoon.sonic.net...

