how to convert const WCHAR * to const char *

c++
92,320

Solution 1

you can also try this:

#include <comdef.h>  // you will need this
const WCHAR* wc = L"Hello World" ;
_bstr_t b(wc);
const char* c = b;
printf("Output: %s\n", c);

_bstr_t implements following conversion operators, which I find quite handy:

operator const wchar_t*( ) const throw( ); 
operator wchar_t*( ) const throw( ); 
operator const char*( ) const; 
operator char*( ) const;

EDIT: clarification with regard to answer comments: line const char* c = b; results in a narrow character copy of the string being created and managed by the _bstr_t instance which will release it once when it is destroyed. The operator just returns a pointer to this copy. Therefore, there is no need to copy this string. Besides, in the question, CString::GetBuffer returns LPTSTR (i.e. TCHAR*) and not LPCTSTR (i.e. const TCHAR*).

Another option is to use conversion macros:

USES_CONVERSION;
const WCHAR* wc = L"Hello World" ;
const char* c = W2A(wc);

The problem with this approach is that the memory for converted string is allocated on stack, so the length of the string is limited. However, this family of conversion macros allow you to select the code page which is to be used for the conversion, which is often needed if wide string contains non-ANSI characters.

Solution 2

You can use sprintf for this purpose:

const char output[256];
const WCHAR* wc = L"Hellow World" ;
sprintf(output, "%ws", wc );

Solution 3

My code for Linux

// Debian GNU/Linux 8 "Jessie" (amd64)

#include <locale.h>
#include <stdlib.h>
#include <stdio.h>

// Use wcstombs(3) to convert Unicode-string (wchar_t *) to UTF-8 (char *)
// http://man7.org/linux/man-pages/man3/wcstombs.3.html

int f(const wchar_t *wcs) {
        setlocale(LC_ALL,"ru_RU.UTF-8");
        printf("Sizeof wchar_t: %d\n", sizeof(wchar_t));
        // on Windows, UTF-16 is internal Unicode encoding (UCS2 before WinXP)
        // on Linux, UCS4 is internal Unicode encoding
        for (int i = 0; wcs[i] > 0; i++) printf("%2d %08X\n",i,wcs[i]);
        char s[256];
        size_t len = wcstombs(s,wcs,sizeof(s));
        if (len > 0) {
                s[len] = '\0';
                printf("mbs: %s\n",s);
                for (int i = 0; i < len; i++)
                        printf("%2d %02X\n",i,(unsigned char)s[i]);
                printf("Size of mbs, in bytes: %d\n",len);
                return 0;
        }
        else return -1;
}

int main() {
        f(L"Привет"); // 6 symbols
        return 0;
}

How to build

#!/bin/sh
NAME=`basename $0 .sh`
CC=/usr/bin/g++-4.9
INCS="-I."
LIBS="-L."
$CC ${NAME}.c -o _${NAME} $INCS $LIBS

Output

$ ./_test 
Sizeof wchar_t: 4
 0 0000041F
 1 00000440
 2 00000438
 3 00000432
 4 00000435
 5 00000442
mbs: Привет
 0 D0
 1 9F
 2 D1
 3 80
 4 D0
 5 B8
 6 D0
 7 B2
 8 D0
 9 B5
10 D1
11 82
Size of mbs, in bytes: 12

Solution 4

You could do this, or you could do something cleaner:

std::wcout << L"output: " << output.GetString() << std::endl;

Solution 5

It's quite easy, because CString is just a typedef for CStringT, and you also have access to CStringA and CStringW (you should read the documentation about the differences).

CStringW myString = L"Hello World";
CString myConvertedString = myString;
Share:
92,320

Related videos on Youtube

jack
Author by

jack

Updated on July 09, 2022

Comments

  • jack
    jack almost 2 years
    CString output ;
    const WCHAR* wc = L"Hellow World" ;
    if( wc != NULL )
    {   
         output.Append(wc);
    }
    printf( "output: %s\n",output.GetBuffer(0) );
    
    • Kao
      Kao over 11 years
      Please add an explanation, as pure code, doesn't say much.
    • MikMik
      MikMik over 11 years
      You don't need GetBuffer. CString has a LPCTSTR operator which accesses the internal buffer.
    • Zdeslav Vojkovic
      Zdeslav Vojkovic over 11 years
      what should be the output if wc is привет мир? do you care about code pages or this is just wide -> narrow conversion with all wide characters being ANSI characters?
  • sehe
    sehe over 11 years
    I'm so tempted to +1 this. _bstr_t and _variant_t used to be my best friends back in the days when you really needed ATL to do a decent COM component in C++
  • Zdeslav Vojkovic
    Zdeslav Vojkovic over 11 years
    why would it copy it? your code shows just that you need to use it in printf. _bstr_t will take care of releasing the memory. If you need to keep a copy and send the string around, use the _bstr_t instance, not const char* - in this sense, _bstr_t is similar to CString. It takes care of copying the string data properly when multiple copies of the object are used (although it doesn't use copy-on-write).
  • jack
    jack over 11 years
    const WCHAR* wc = L"Hellow World" ; c = _bstr_t(wc);printf( "output: %s\n",c );
  • Rost
    Rost over 11 years
    Why to use GetBuffer()? Here is GetString() official C-string getter!
  • Luchian Grigore
    Luchian Grigore over 11 years
    @Rost copy-paste :D No need to yell :D
  • Rost
    Rost over 11 years
    Copy-paste is evil!!! Real developers always retype char by char! Don't you know?!? :-D
  • jack
    jack over 11 years
    output is like this: ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■‌​ε■ε■ε■ε■ε■ε■
  • Zdeslav Vojkovic
    Zdeslav Vojkovic over 11 years
    is your _bstr_t object still alive at that moment? According to your code sample it is.
  • Zdeslav Vojkovic
    Zdeslav Vojkovic over 11 years
    I have tried exaclty the same code as in my answer, and it works.
  • Zdeslav Vojkovic
    Zdeslav Vojkovic over 11 years
    ooops, sorry, wrote to quickly! see the updated code sample. You were completely right: the original code created a temporary bstr_t which was destroyed immediately after assignment to c. I was typing faster than I was thinking, sorry for confusion.
  • Adam McKee
    Adam McKee over 11 years
    Yes, I realise that, but it was written that way to be closer to his example code.
  • M.M
    M.M about 10 years
    What does this conversion do with wide chars that don't have a matching narrow char?
  • CinCout
    CinCout almost 8 years
    I don't think you can declare output as const