字符串表示与转换
Posted luofeiju
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字符串表示与转换相关的知识,希望对你有一定的参考价值。
windows 编程中,存在几种字符串表示方式,包括:
1)C-Style 字符串 char* / wchar_t*;
2)C++ STL 字符串 std::string / std::wstring;
3) ATL/MFC 字符串 CStringA / CStringW;
以上每个版本都有对应的多字节(MBCS)与Unicode(DBCS)表示,其中多字节存在不同编码方案,使用代码页区分。在 windows 系统中,常见代码页有:
1)MS-DOS Latin US, code page 437,使用一个八位字节表示拉丁字符;
2)windows code page 1251 for Cyrillic, 使用一个八位字节表示斯拉夫字符;
3)code page 936/950/932/949 for ideographic,分别表示 简体中文/繁体中文/日语/韩语,使用一个八位字符表示拉丁字符,使用两个八位字符表示象形文字;
针对象形文字,使用 strlen 函数求字符串长度是没有意义的,strlen 函数简单返回字符串中以 ‘ ‘ 结尾前字符个数。
Unicode 使用两个字节表示一个字符,前128位与 ASCII(American Standard Code for Information Interchange) 保持一致。在使用非象形文字时语言时,有一半空间被浪费,故基于 Unicode 字符进行在编码,形成 utf8。这样,针对拉丁语系,斯拉夫语系等仅需要一个字符表示 Unicode 编码,而象形文字使用2,3,4个字节编码,具体见博客 ”字符集及编码“。在 visual c++开发中,utf8 编码可看作一种特殊代码页,使用函数 WideCharToMultiByte(CP_UTF8,...) 可以得到。
如何维护在一个源文件中维护两种编码方案(MBCS & UNICODE)?
winows 系统如下定义:
1 typedef wchar_t WCHAR; // wc, 16-bit UNICODE character 2 3 #ifdef UNICODE 4 // PTCHAR is a pointer to WCHAR 5 typedef WCHAR TCHAR, *PTCHAR; 6 #else 7 // PTCHAR is a pointer to char 8 typedef char TCHAR, *PTCHAR; 9 #endif 10 11 #ifdef _UNICODE 12 #define _tcscpy wcscpy 13 #define _tcslen wcslen 14 ... 15 #else 16 #define _tcscpy strcpy 17 #define _tcslen strlen 18 ... 19 #endif 20 21 #ifdef _UNICODE 22 #define __T(x) L ## x 23 #define __TEXT(quote) L##quote 24 #else 25 #define __T(x) x 26 #define __TEXT(quote) quote 27 #endif 28 29 // _T(x) __T(x) TEXT(x) _TEXT(x) __TEXT(x) same meaning 30 #define _T(x) __T(x) 31 #define _TEXT(x) __T(x) 32 #define TEXT(quote) __TEXT(quote)
根据以上定义,可以在使用一个源文件维护 C-Style 字符串,具体如下:
1 TCHAR *sz = _T("ch中国"); 2 int iLen = _tcslen(sz); 3 TCHAR *sz2 = new TCHAR[iLen + 1]; 4 _tcscpy(sz2, sz); 5 delete []sz2;
在项目 Properties->Configuration Prooperties->General 下选择 Use Multi-Byte Character Set(or Not Set ),iLen 值为 6,其中每个汉字使用两个字节;当选择 Use Unicode Character Set 时,iLen 值为 4, 表示 sz 有 4 个字符。
C++ STL 字符串 与 ATL/MFC 字符串是对 TCHAR 字符数据进行封装,表示如下:
1 // c++ string 2 typedef basic_string<char, char_traits<char>, allocator<char> > 3 string; 4 typedef basic_string<wchar_t, char_traits<wchar_t>, 5 allocator<wchar_t> > wstring; 6 7 // atl/mfc string 8 typedef ATL::CStringT< wchar_t, StrTraitMFC_DLL< wchar_t > > CStringW; 9 typedef ATL::CStringT< char, StrTraitMFC_DLL< char > > CStringA; 10 typedef ATL::CStringT< TCHAR, StrTraitMFC_DLL< TCHAR > > CString; 11 12 // 由于c++ string 没有提供一个 TCHAR 版本,通过增加如下定义, 13 // 实现多字节与Unicode自动转换 14 #ifdef _UNICODE 15 #define tstring std::wstring 16 #else 17 #define tstring std::string 18 #endif
通过以上定义,使用 tstring(自定义),CString 可以在一个源文件中维护两种类型字符串。windows 也允许使用特定字符集字符串,提供了 MBCS/Unicode 之间转换函数,具体如下:
1 // char* -> wchar_t* 2 //char *sz1 = "ch中国"; 3 // 获取 sz1 字符串转换为 Unicode 长度 4 int iLen = MultiByteToWideChar(CP_ACP, 0, sz1, strlen(sz1), NULL, 0); 5 wchar_t* sz2 = new wchar_t[iLen + 1]; 6 MultiByteToWideChar(CP_ACP, 0, sz1, strlen(sz1), sz2, iLen); 7 sz2[iLen] = ‘