CString output ;
const WCHAR* wc = L"Hellow World" ;
if( wc != NULL )
{
output.Append(wc);
}
printf( "output: %s\n",output.GetBuffer(0) );
7 回答
你也可以试试这个:
#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
(ie TCHAR*
) 而不是 LPCTSTR
(ie const TCHAR*
)。
另一种选择是使用转换宏:
USES_CONVERSION;
const WCHAR* wc = L"Hello World" ;
const char* c = W2A(wc);
这种方法的问题是转换后的字符串的内存是在堆栈上分配的,因此字符串的长度是有限的。但是,这一系列转换宏允许您选择要用于转换的代码页,如果宽字符串包含非 ANSI 字符,则通常需要此代码页。
您可以sprintf
为此目的使用:
const char output[256];
const WCHAR* wc = L"Hellow World" ;
sprintf(output, "%ws", wc );
我的 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
你可以这样做,或者你可以做一些更清洁的事情:
std::wcout << L"output: " << output.GetString() << std::endl;
这很简单,因为CString
它只是一个 typedef CStringT
,并且您还可以访问CStringA
and CStringW
(您应该阅读有关差异的文档)。
CStringW myString = L"Hello World";
CString myConvertedString = myString;
正如@l0pan 提到的那样,您可以将sprintf
其用于此目的(但我使用%ls
的是%ws
):
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
您可以使用该std::wcsrtombs
功能。
这是用于转换的C++17重载集:
#include <iostream> // not required for the conversion function
// required for conversion
#include <cuchar>
#include <cwchar>
#include <stdexcept>
#include <string>
#include <string_view> // for std::wstring_view overload
std::string to_string(wchar_t const* wcstr){
auto s = std::mbstate_t();
auto const target_char_count = std::wcsrtombs(nullptr, &wcstr, 0, &s);
if(target_char_count == static_cast<std::size_t>(-1)){
throw std::logic_error("Illegal byte sequence");
}
// +1 because std::string adds a null terminator which isn't part of size
auto str = std::string(target_char_count, '\0');
std::wcsrtombs(str.data(), &wcstr, str.size() + 1, &s);
return str;
}
std::string to_string(std::wstring const& wstr){
return to_string(wstr.c_str());
}
std::string to_string(std::wstring_view const& view){
// wstring because wstring_view is not required to be null-terminated!
return to_string(std::wstring(view));
}
int main(){
using namespace std::literals;
std::cout
<< to_string(L"wchar_t const*") << "\n"
<< to_string(L"std::wstring"s) << "\n"
<< to_string(L"std::wstring_view"sv) << "\n";
}
如果你使用 Pre-C++17,你应该紧急更新你的编译器!;-)
如果这真的不可能,这里有一个 C++11 版本:
#include <iostream> // not required for the conversion function
// required for conversion
#include <cwchar>
#include <stdexcept>
#include <string>
std::string to_string(wchar_t const* wcstr){
auto s = std::mbstate_t();
auto const target_char_count = std::wcsrtombs(nullptr, &wcstr, 0, &s);
if(target_char_count == static_cast<std::size_t>(-1)){
throw std::logic_error("Illegal byte sequence");
}
// +1 because std::string adds a null terminator which isn't part of size
auto str = std::string(target_char_count, '\0');
std::wcsrtombs(const_cast<char*>(str.data()), &wcstr, str.size() + 1, &s);
return str;
}
std::string to_string(std::wstring const& wstr){
return to_string(wstr.c_str());
}
int main(){
std::cout
<< to_string(L"wchar_t const*") << "\n"
<< to_string(std::wstring(L"std::wstring")) << "\n";
}