以下两段代码的执行环境是 windows xp professional 英文版,编译器是 VS2005RTM。
// C
#include <stdio.h>
#include <locale.h>
int main( void )
{
setlocale( LC_ALL, "chs" );
//setlocale( LC_ALL, "Chinese-simplified" );
//setlocale( LC_ALL, "ZHI" );
//setlocale( LC_ALL, ".936" );
wprintf( L"中国" );
return 0;
}
// C++
#include <iostream>
#include <locale>
using namespace std;
int main( void )
{
locale loc( "chs" );
//locale loc( "Chinese-simplified" );
//locale loc( "ZHI" );
//locale loc( ".936" );
wcout.imbue( loc );
std::wcout << L"中国" << endl;
return 0;
}
说明:别混合使用 setlocale 和 std::locale 。
------------------------- 2006-07-05 记 -------------------------
"VC知识库" 编码为:56 43 D6 AA CA B6 BF E2 00 // ANSI编码
L"VC知识库" 在VC++ 中编码为:56 00 43 00 E5 77 C6 8B 93 5E 00 00 // (windows口中的unicode)编码
L"VC知识库" 在GCC(Dev-CPP4990) 中编码为:56 00 43 00 D6 00 AA 00 CA 00 B6 00 BF 00 E2 00 00 00 // 只是将ANSI编码简单的加0
L"VC知识库" 在GCC(Dev-CPP4992) 中编译失败,报 Illegal byte sequence
L"VC知识库" 在 Dev-CPP4992 中解决步骤为:
a. 将文件保存为 utf-8 编码 // utf-8 是unicode的其中一种,但和(windows口中的unicode)不一样
b. 去掉BOM头:用二进制编辑器(比如VC)去掉刚才utf-8文件的前三个字节 // Linux/UNIX并不使用BOM
c. 使用 gcc/g++ 编译运行
经过以上解决步骤,在 dev-cpp4992 中
"VC知识库" 编码为: 56 43 E7 9F A5 E8 AF 86 E5 BA 93 00 // utf-8编码,注意不再是ANSI编码了,因此用 printf/cout 将输出乱码
L"VC知识库" 编码为: 56 00 43 00 E5 77 C6 8B 93 5E 00 00 // (windows口中的unicode)编码
补充:在mingw32中使用wcout和wstring需要加一些宏,比如
#define _GLIBCXX_USE_WCHAR_T 1
#include <iostream>
int main( void )
{
std::wcout << 1 << std::endl;
}
可以编译通过,但无法Link通过,在网上google了一下,stlport说mingw32有问题,mingw32说是M$的c runtime有问题。
------------------------- 2007-01-05 记 -------------------------
一个多字节字符串和宽字符字符串互相转化的事例
#define _CRT_SECURE_NO_WARNINGS // only for vc8
#include <string>
#include <clocale>
#include <cassert>
inline const std::string to_mbcs( const std::string& src )
{
return src;
}
const std::string to_mbcs( const std::wstring& src )
{
char* old_locale = _strdup( setlocale(LC_CTYPE,NULL) ); // 保存原来的locale
setlocale( LC_CTYPE, "chs" ); // 设置当前locale为chs,这在非简体中文平台上不可缺少
size_t count1 = wcstombs( NULL, src.c_str(), 0 ); // 计算新字符串长度
std::string des( count1, ' ' );
size_t count2 = wcstombs( &des[0], src.c_str(), count1 ); // 转化
assert( count1 == count2 );
setlocale( LC_CTYPE, old_locale ); // 恢复到原来的locale
free( old_locale );
return des;
}
inline const std::wstring to_wcs( const std::wstring& src )
{
return src;
}
const std::wstring to_wcs( const std::string& src )
{
char* old_locale = _strdup( setlocale(LC_CTYPE,NULL) ); // 保存原来的locale
setlocale( LC_CTYPE, "chs" ); // 设置当前locale为chs,这在非简体中文平台上不可缺少
size_t count1 = mbstowcs( NULL, src.c_str(), 0 ); // 计算新字符串长度
std::wstring des( count1, L' ' );
size_t count2 = mbstowcs( &des[0], src.c_str(), count1 ); // 转化
assert( count1 == count2 );
setlocale( LC_CTYPE, old_locale ); // 恢复到原来的locale
free( old_locale );
return des;
}
#include <iostream>
int main( void )
{
using namespace std;
cout << to_mbcs("你好1") << endl;
cout << to_mbcs(L"你好2") << endl;
const locale loc( "chs" );
wcout.imbue( loc );
wcout << to_wcs("你好3") << endl;
wcout << to_wcs(L"你好4") << endl;
}
另外共享另外一个我的东东:
#include <windows.h>
#include <strstream>
#include <iostream>
using namespace std;
bool c2w( wchar_t* outputstr, const char* inputstr,int size )
{
// inputstr : str = "25105#25106"
// outputstr : 有足够的空间 wchar_t wsz[256];
// 如果不提供size,可以在函数中使用std::count计算个数
int count = 0;
DWORD tmp = 0;
char t;
istrstream istr( inputstr );
while( count < size )
{
istr>>tmp;
*( outputstr + count ) = static_cast<wchar_t>( tmp );
++count;
if( count <size )
istr>>t;
}
*( outputstr + count ) = 0;
return true;
}
int main()
{
wchar_t ex[10];
const char* inputstr = "25105 # 26159 # 29482";
c2w( ex,inputstr,3 );
// C++ 方式
locale loc( "chs" );
wcout.imbue( loc );
wcout<<ex<<endl;
// C方式
//setlocale( LC_ALL, "chs" );
//wprintf(L"%s/n",ex );
// Windows方式
// MessageBoxW(NULL,ex,L"例子",0 );
return 0;
}