字符与编码

摘自:白乔, 左飞. 把脉VC++. 2009年7月. P176, P183~187.
 
1. 概念
  • 多字节字符集:MBCS,Multi-Bytes Charecter Set,是一种不同长度混排的编码方法。这种编码被称为GB2312,与ASCII码兼容。如:"中文ABC"所占的字节数是 2*2+3 = 7。
  • 宽字节字符:使用UNICODE编码进行存放的字符。
2. 转换
  • mbtowc:将多字节字符转换成wchar_t;
  • wctomb:将wchar_t转换成多字节字符;
  • mbstowcs:将多字节字符串转换成wchar_t字符串;
  • wcstombs:将wchar_t字符串转换成多字节字符串。

注:头文件是stdlib.h或cstdlib;
   
除mbtowc外,其它都有对应的_s版本,应使用_s版。

 

    UNICODE字符集和MBCS字符集之间的转换方法还可以利用Windows提供的转换函数WideCharToMultiByte()和MultiByteToWideChar()来完成。函数原型如下:
int WideCharToMultiByte( UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar ); int MultiByteToWideChar( UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar );
    WideCharToMultiByte()用来将宽字节字符转换成MBCS,MultiByteToWideChar()用来将MBCS转换成宽字符。通常情况下,可能开始并不知道转换之后的字符串会占用多大的字节,这时可以将参数cbMultiByte置为0 ,预先调用一次WideCharToMultiByte()和MultiByteToWideChar(),它们的返回值即为目标字符串的字节大小,然后再利用该大小作为参数 cbMultiByte,再次调用函数即可。
 
    此外,也可以用_bstr_t类来实现字符编码的转换。_bstr_t的构造函数如下:
_bstr_t() throw(); _bstr_t( const _bstr_t& s1 ) throw(); _bstr_t( const char* s2 ); _bstr_t( const wchar_t* s3 ); _bstr_t( const _variant_t& var ); _bstr_t( BSTR bstr, bool fCopy );
    可以看出,_bstr_t同时支持 char* 和 wchar_t* 类型。_bstr_t提供了如下转换操作符函数:
operator const wchar_t*() const throw(); operator wchar_t*() const throw(); operator const char*() const; operator char*() const;
    示例代码:
#include "comutil.h" #pragma comment(lib, "comsuppw.lib") // 或 comsuppwd.lib int main() { setlocale(LC_ALL, "chs"); char s1[] = "中文ABC"; wchar_t s2[] = L"武林外传"; // 使用xtoy转换 // s2-->p1 // 第一次调用,计算MBCS字符串字节长度 int len1 = WideCharToMultiByte( CP_ACP, 0, s2, // 宽字符串指针 sizeof(s2), // 宽字符串长度 NULL, 0, // 参数0表示计算转换后的字符空间 NULL, NULL); char* p1 = new char[len1]; WideCharToMultiByte( CP_ACP, 0, s2, // 宽字符串指针 sizeof(s2), // 宽字符串长度 p1, // 转换后的字符串指针 len1, // 给出空间大小 NULL, NULL); printf("%s/r/n", p1); delete [] p1; // s1-->p2 // 第一次调用,计算宽字符串字节长度 int len2 = MultiByteToWideChar( CP_ACP, 0, s1, // MBCS字符串指针 sizeof(s1), // MBCS字符串长度 NULL, 0); wchar_t* p2 = new wchar_t[len2]; MultiByteToWideChar( CP_ACP, 0, s1, // MBCS字符串指针 sizeof(s1), // MBCS字符串长度 p2, // 转换后的字符串指针 len2); printf("%S/r/n", p2); delete [] p2; // 使用BSTR完成转换 _bstr_t bs1(s1); _bstr_t bs2(s2); char* bp1 = bs2; printf("%s/r/n", bp1); wchar_t* bp2 = bs1; printf("%S/r/n", bp2); return 0; }

 

 
3. 编写通用的程序

  • 在编程的时候使用TCHAR数据类型,此类型能够根据预编译宏的定义,将其转换为ANSI或者是Unicode;
  • 预编译宏_MBCS、_UNICODE和UNICODE。_MBCS是多字节和ANSI字符串的编译宏,此时TCHAR将转换为char。_UNICODE和UNICODE是Unicode编码的预编译宏,TCHAR将转换为wchar_t;
  • _UNICODE和UNICODE与_MBCS不能在编译的时候同时被定义;
  • _UNICODE宏用于C运行期库的头文件,UNICODE宏用于Windows头文件,一般同时定义这两个宏。

你可能感兴趣的:(字符与编码)