C++ 如何将常量WCHAR*转换为常量char*

C++ 如何将常量WCHAR*转换为常量char*,c++,C++,你可以这样做,也可以做一些更干净的事情: CString output ; const WCHAR* wc = L"Hellow World" ; if( wc != NULL ) { output.Append(wc); } printf( "output: %s\n",output.GetBuffer(0) ); std::wcout您也可以尝试以下方法: std::wcout << L"output: " << output.GetString()

你可以这样做,也可以做一些更干净的事情:

CString output ;
const WCHAR* wc = L"Hellow World" ;
if( wc != NULL )
{   
     output.Append(wc);
}
printf( "output: %s\n",output.GetBuffer(0) );
std::wcout您也可以尝试以下方法:

std::wcout << L"output: " << output.GetString() << std::endl;
编辑:关于回答意见的澄清:行
const char*c=b
导致字符串的窄字符副本由
\u bstr\u t
实例创建和管理,该实例将在销毁该字符串时释放该字符串。运算符只返回指向此副本的指针。因此,不需要复制此字符串。此外,在问题中,
CString::GetBuffer
返回
LPTSTR
(即
TCHAR*
)和
LPCTSTR
(即
consttchar*

另一个选项是使用转换宏:

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

这种方法的问题是,转换字符串的内存是在堆栈上分配的,因此字符串的长度是有限的。但是,此转换宏系列允许您选择用于转换的代码页,如果宽字符串包含非ANSI字符,则通常需要此代码页。

这很容易,因为
CString
只是
CStringT
的typedef,您还可以访问
CStringA
CStringW
(您应该阅读有关差异的文档)


为此,您可以使用
sprintf

CStringW myString = L"Hello World";
CString myConvertedString = myString;
我的Linux代码

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

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

您可以使用
sprintf
,正如@l0pan提到的那样(但我使用了
%ls
而不是
%ws
):


我很想+1这个<代码>\u bstr\u t
\u variant\u t
过去是我最好的朋友,那时你真的需要ATL在C++中制作一个像样的COM组件,为什么它要复制它?您的代码只显示您需要在
printf
中使用它<代码>\u bstr\u t将负责释放内存。如果需要保留副本并发送字符串,请使用
\u bstr\u t
实例,而不是
const char*
——从这个意义上讲,
\u bstr\u t
类似于
CString
。当使用对象的多个副本时,它负责正确复制字符串数据(尽管它不使用写时复制);c=t(wc);printf(“输出:%s\n”,c);输出如下:ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■ε■你的物体在那一刻还活着吗?根据您的代码示例,它是。请添加一个解释,因为纯代码没有太多说明。您不需要GetBuffer。CString有一个访问内部缓冲区的LPCTSTR运算符。如果
wc
Пцццццц
,输出应该是什么?您是否关心代码页,或者这只是宽->窄转换,所有宽字符都是ANSI字符?为什么要使用
GetBuffer()
?这里是
GetString()
官方C-string getter@罗斯特复制粘贴:D不需要大喊:复制粘贴是邪恶的!!!真正的开发人员总是一个字符一个字符地重新键入字符!你不知道吗-Diges,我意识到了这一点,但这样写是为了更接近他的示例代码。这种转换对没有匹配窄字符的宽字符有什么作用?我不认为您可以将
输出
声明为
常量
const char output[256];
const WCHAR* wc = L"Hellow World" ;
sprintf(output, "%ws", wc );
// 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;
}
#!/bin/sh
NAME=`basename $0 .sh`
CC=/usr/bin/g++-4.9
INCS="-I."
LIBS="-L."
$CC ${NAME}.c -o _${NAME} $INCS $LIBS
$ ./_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
char output[256];
const WCHAR* wc = L"Hello World" ;
sprintf(output, "%ws", wc ); // did not work for me (Windows, C++ Builder)
sprintf(output, "%ls", wc ); // works