ChefZ -- 磨劍錄 (A Coder's Log)

慣看秋月春風 一壺濁酒喜相逢 古今多少事 皆賦談笑中
posts - 42, comments - 3, trackbacks - 0, articles - 6
Any way to convert a WCHAR string to a CHAR string?

Well.. such a conversion would only make sense if your WCHAR string only consisted of characters that can also be represented using CHAR. In that case, yiu can write a conversion function:

CHAR wide_to_narrow(WCHAR w)
{
// simple typecast
// works because UNICODE incorporates ASCII into itself
return CHAR(w);
}
Now, you can perform the conversion using std::transform():

WCHAR[20] wstr = "blahblahandmoreblah";
CHAR[20] dest;
std::transform(wstr, wstr + 20, dest, wide_to_narrow);

Or, even better, use wstring and string instead of WCHAR and CHAR arrays:

std::wstring wstr = "blahblahandmoreblah";
std::string dest(wstr.length());
std::transform(wstr.begin(), wstr.end(), dest.begin(), wide_to_narrow);

Simple isn't it?

when using wstring and string, do I have to use transform?

I guess I failed to offer more specific details concerning my problem.

I'm dealing with a structure that, when returned from a function, contains a member with the data type of PWSTR. I need to convert this string in this structure to a CHAR*, so that I can output it using std::cout.

In your examples, you know the size of the WCHAR*, but in my case I don't know the size of the string that I need to convert, so it would be impossible to use std::transform without the appropriate iterators.

**EDIT**

I fixed it, thanks for the help though.

Here is what I have. These functions assume the destination buffer is large enough to contain the source after conversion. Buffer overrun errors could occur if the assumption is proven false:



//=====================================================================================
/*
|| ::DESCRIPTION::
|| This function will convert a WCHAR string to a CHAR string.
||
|| Param 1 :: Pointer to a buffer that will contain the converted string. Ensure this
|| buffer is large enough; if not, buffer overrun errors will occur.
|| Param 2 :: Constant pointer to a source WCHAR string to be converted to CHAR
*/
void wtoc(CHAR* Dest, const WCHAR* Source)
{
int i = 0;

while(Source[i] != '\0')
{
Dest[i] = (CHAR)Source[i];
++i;
}
}

//=====================================================================================
/*
|| ::DESCRIPTION::
|| This function will convert a CHAR string to a WCHAR string.
||
|| Param 1 :: Pointer to a buffer that will contain the converted string. Ensure this
|| buffer is large enough; if not, buffer overrun errors will occur.
|| Param 2 :: Constant pointer to a source CHAR string to be converted to WCHAR
*/
void ctow(WCHAR* Dest, const CHAR* Source)
{
int i = 0;

while(Source[i] != '\0')
{
Dest[i] = (WCHAR)Source[i];
++i;
}
}

Since many unicode characters maps to ASCII characters (for example in the Greek table, there is also the characters 'A' to 'Z'), to convert an unicode string to ansi, a simple cast is not convenient.

But there is a Win32 api, WideCharToMultiByte (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/unicode_2bj9.asp).
And, it can also converts unicode to OEM.

Here is an example of usage:

#define STRICT
#include <windows.h>
#include <iostream.h>

using namespace std;

LPSTR UnicodeToAnsi(LPCWSTR s)
{
if (s==NULL) return NULL;
int cw=lstrlenW(s);
if (cw==0) {CHAR *psz=new CHAR[1];*psz='\0';return psz;}
int cc=WideCharToMultiByte(CP_ACP,0,s,cw,NULL,0,NULL,NULL);
if (cc==0) return NULL;
CHAR *psz=new CHAR[cc+1];
cc=WideCharToMultiByte(CP_ACP,0,s,cw,psz,cc,NULL,NULL);
if (cc==0) {delete[] psz;return NULL;}
psz[cc]='\0';
return psz;
}

int main()
{
LPSTR psz=UnicodeToAnsi(L"Hello, my friend!");
cout<<psz;
delete[] psz;
return 0;


In your examples, you know the size of the WCHAR*, but in my case I don't know the size of the string that I need to convert, so it would be impossible to use std::transform without the appropriate iterators.

If you assigned teh WCHAR array to a wstring, it would automatically stop copying characters at the null character, and then the length() member function would return the length of the wstring.

WCHAR* w = getWcharPointerWithoutKnowingItsSize();
wstring wstr = w;

Here, wstr.length() would yield the size.

Also, I don't know if it's standard, but some compilers provide a wstrlen() function that acts like strlen(), only on wide-character strings.

Feedback

# re: 【转】Convert a WCHAR string to a CHAR string?  回复  更多评论   

2010-11-15 18:38 by 南通SEO
好好,写得非常棒!

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理