2012-09-28 243 views
7
CString output ; 
const WCHAR* wc = L"Hellow World" ; 
if(wc != NULL) 
{ 
    output.Append(wc); 
} 
printf("output: %s\n",output.GetBuffer(0)); 
+0

请添加说明,因为纯代码不会说太多。 – Kao

+0

你不需要GetBuffer。 CString有一个访问内部缓冲区的LPCTSTR操作符。 – MikMik

+1

如果'wc'是'приветмир',应该输出什么?你关心的代码页或这只是宽 - 窄转换所有宽字符是ANSI字符? –

回答

12

你也可以试试这个:

#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工具以下转换运算符,我发现它很方便:

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

编辑:关于回答评论的说明:行const char* c = b;导致正在创建并由_bstr_t实例管理的字符串的窄字符副本,该实例将在销毁时释放一次。运算符只是返回一个指向这个副本的指针。因此,不需要复制该字符串。此外,在该问题中,CString::GetBuffer返回LPTSTR(即TCHAR*)和而不是LPCTSTR(即const TCHAR*)。

另一种选择是使用转换宏:

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

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

+0

我很想尝试+1。当你真的需要ATL在C++ – sehe

+0

中做一个体面的COM组件时,'_bstr_t'和'_variant_t'曾经是我最好的朋友,但它没有将wc复制到c – jack

+0

为什么要复制它?你的代码只显示你需要在'printf'中使用它。 '_bstr_t'将负责释放内存。如果需要保留副本并发送字符串,请使用'_bstr_t'实例,而不是'const char *' - 从这个意义上说,'_bstr_t'与'CString'类似。当使用对象的多个副本时(尽管它不使用* copy-on-write *),它会正确地复制字符串数据。 –

1

你可以这样做,或者你可以做一些清洁剂:

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

为什么要使用'GetBuffer()'?这里是'GetString()'官方C字符串getter! – Rost

+0

@复制粘贴:D无需大喊:D –

+2

复制粘贴是邪恶的!真正的开发人员总是通过char重新输入char!你不知道吗?!? :-D – Rost

1

这是很容易的,因为CString仅仅是CStringT一个typedef,你也有机会获得CStringACStringW(你应该阅读有关差异的文档)。

CStringW myString = L"Hello World"; 
CString myConvertedString = myString; 
+0

'CStringA myConvertedString(L“Hello World”);'也可以工作 – Rost

+0

是的,我意识到这一点,但它写的更接近他的示例代码。 –

+0

此转换对没有匹配窄字符的宽字符做什么? –

5

您可以使用sprintf用于此目的:

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

我不认为你可以将'output'声明为'const' – CinCout

2

我对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; 
} 

代码如何建立

#!/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