David的测试技术空间,收藏好文档和分享我的技术理解。5年的数通产品测试和安全产品测试经验,3年Web产品测试和多年测试管理和测试工具开发经验。目前关注性能分析调优、Jmeter和TestNG+WebDriver+Hamcrest的培训推广。Welcome沟通交流,请留言或者发邮件到daviwang_2004 at soguo.com。

Q: How to convert between ANSI and UNICODE strings?

上一篇 / 下一篇  2008-01-30 09:13:50 / 个人分类:旧资料

Q: How to convert between ANSI and UNICODE strings?
copy from :http://www.codeguru.com/forum/archive/index.php/t-231165.html



A:

The quick and dirty way

This way of working is correct for codepages that are single-byte and Unicode strings that are UCS2. This applies to most cases, but if your program should run correctly on Japanese, Chinese, Taiwanese and other systems which have DBCS codepages then use the "correct way" described further below.

ANSI to UNICODE:

The conversion is done using the 'MultiByteToWideChar()' function:


char *ansistr = "Hello";
int a = lstrlenA(ansistr);
BSTR unicodestr = SysAllocStringLen(NULL, a);
::MultiByteToWideChar(CP_ACP, 0, ansistr, a, unicodestr, a);
//... when done, free the BSTR
::SysFreeString(unicodestr);


UNICODE to ANSI:

The UNICODE string mostly is returned by some COM function, like this one:


HRESULT SomeCOMFunction(BSTR *bstr)
{
*bstr = ::SysAllocString(L"Hello");
return S_OK;
}

The conversion is done using the 'WideCharToMultiByte()' function:


BSTR unicodestr = 0;
SomeCOMFunction(&unicodestr);
int a = SysStringLen(unicodestr)+1;
char *ansistr = new char[a];
::WideCharToMultiByte(CP_ACP,
0,
unicodestr,
-1,
ansistr,
a,
NULL,
NULL);
//...use the strings, then free their memory:
delete[] ansistr;
::SysFreeString(unicodestr);


The correct way

If you want to handle DBCS codepages and UTF-16 Unicode strings then you should do things this way. The idea is to call 'MultiByteToWideChar()' resp. 'WideCharToMultiByte()' twice. First you get the length of the result, then you allocate the resulting string and call it again to convert.

ANSI to Unicode


char *ansistr = "Hello"
int lenA = lstrlenA(ansistr);
int lenW;
BSTR unicodestr;

lenW = ::MultiByteToWideChar(CP_ACP, 0, ansistr, lenA, 0, 0);
if (lenW > 0)
{
// Check whether conversion was successful
unicodestr = ::SysAllocStringLen(0, lenW);
::MultiByteToWideChar(CP_ACP, 0, ansistr, lenA, unicodestr, lenW);
}
else
{
// handle the error
}

// when done, free the BSTR
::SysFreeString(unicodestr);


Unicode to ANSI


BSTR unicodestr = 0;
char *ansistr;
SomeCOMFunction(&unicodestr);
int lenW = ::SysStringLen(unicodestr);
int lenA = ::WideCharToMultiByte(CP_ACP, 0, unicodestr, lenW, 0, 0, NULL, NULL);
if (lenA > 0)
{
ansistr = new char[lenA + 1]; // allocate a final null terminator as well
::WideCharToMultiByte(CP_ACP, 0, unicodestr, lenW, ansistr, lenA, NULL, NULL);
ansistr[lenA] = 0; // Set the null terminator yourself
}
else
{
// handle the error
}

//...use the strings, then free their memory:
delete[] ansistr;
::SysFreeString(unicodestr);

TAG: 与目前工作有关的杂项

 

评分:0

我来说两句

Open Toolbar