CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5

Thread: WCHAR* to CHAR*

  1. #1
    Join Date
    Feb 2004
    Location
    Texas, USA
    Posts
    1,206

    WCHAR* to CHAR*

    Any way to convert a WCHAR string to a CHAR string?

  2. #2
    Join Date
    Apr 2004
    Location
    Canada
    Posts
    1,342

    Re: WCHAR* to CHAR*

    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:

    Code:
    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():

    Code:
    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:

    Code:
    std::wstring wstr = "blahblahandmoreblah";
    std::string dest(wstr.length());
    std::transform(wstr.begin(), wstr.end(), dest.begin(), wide_to_narrow);
    Simple isn't it?
    Old Unix programmers never die, they just mv to /dev/null

  3. #3
    Join Date
    Feb 2004
    Location
    Texas, USA
    Posts
    1,206

    Re: WCHAR* to CHAR*

    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:

    Code:
    //=====================================================================================
    /*
    || ::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;
        }
    }
    Last edited by MrDoomMaster; April 9th, 2005 at 01:18 PM.

  4. #4
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Re: WCHAR* to CHAR*

    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.
    And, it can also converts unicode to OEM.

    Here is an example of usage:
    Code:
    #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;
    }
    Last edited by SuperKoko; April 9th, 2005 at 05:25 PM.

  5. #5
    Join Date
    Apr 2004
    Location
    Canada
    Posts
    1,342

    Re: WCHAR* to CHAR*

    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.

    Code:
    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.
    Old Unix programmers never die, they just mv to /dev/null

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured