Unicode编程

来源:互联网 发布:软件角色管理 编辑:程序博客网 时间:2024/05/20 04:31

1.Windows定义的Unicode数据类型有哪些?
数据类型 说明
WCHAR Unicode字符(源自系统宏定义typedef wchar_t WCHAR;)
PWSTR 指向Unicode字符串的指针
PCWSTR 指向一个恒定的Unicode字符串的指针
对应的ANSI数据类型为CHAR,LPSTR和LPCSTR。

LPCTSTRconst TCHAR*是完全等同的。其中L表示long指针,Ppointer)表示这是一个指针Cconst)表示是一个常量T(_T)表示兼容ANSIUnicodeSTRstring)表示这个变量是一个字符串

Win32 API在winnt.h头文件中定义了一些实现字符和常量字符串的宏进行ANSI/Unicode通用编程。
ANSI/Unicode通用数据类型为TCHAR,PTSTR,LPCTSTR。

#ifdefUNICODE // 注意此处没有没有下划线

typedef WCHAR         TCHAR, *PTCHAR;

typedef LPWSTR        LPTCH, PTCH;

typedef LPWSTR        PTSTR, LPTSTR;

typedef LPCWSTR       LPCTSTR;

#define __TEXT(quote) L##quote        // r_winnt

 

#else                        // r_winnt

        typedef char          TCHAR, *PTCHAR;

        typedef LPSTR         LPTCH, PTCH;

        typedef LPSTR         PTSTR, LPTSTR;

        typedef LPCSTR        LPCTSTR;

        #define __TEXT(quote) quote           // r_winnt

#endif                      // r_winnt

2.如何编写Unicode源代码?

只需要定义两个宏(UNICODE和 _UNICODE),就可以修改然后重新编译该源文件。
_UNICODE宏用于C运行期头文件,而UNICODE宏则用于Windows头文件。当编译源代码模块时,通常必须同时定义这两个宏。

3.如何对Unicode进行操作?
  1. ANSI操作函数:          以str开头,如strcpy(),strcat(),strlen();
    2. Unicode操作函数:      以wcs开头,如wcscpy,wcscpy(),wcslen();
    3. ANSI/Unicode操作函数: 以_tcs开头 _tcscpy(C运行期库);
    4. ANSI/Unicode操作函数: 以lstr开头 lstrcpy(Windows函数);
考虑ANSI和Unicode的兼容,我们需要使用以_tcs开头或lstr开头的通用字符串操作函数。
所有新的和未过时的函数在Windows2000中都同时拥有ANSI和Unicode两个版本。ANSI版本函数结尾以A表示;Unicode版本函数结尾以W表示。Windows会如下定义:
#ifdef UNICODE
#define CreateWindowEx CreateWindowExW
#else
#define CreateWindowEx CreateWindowExA
#endif // !UNICODE

注意:使用函数strlenwcslen都是获得的字符串的长度,使用sizeof()可获得耗用内存空间

4.如何表示Unicode字符串常量?

字符集 实例
ANSI “string”
Unicode L“string”
ANSI/Unicode T(“string”)或_TEXT(“string”)if( szError[0] == _TEXT(‘J’) ){ }

5.如何编写符合ANSIUnicode的应用程序?
(1)将文本串视为字符数组,而不是chars数组或字节数组。
(2)将通用数据类型(如TCHAR和PTSTR)用于文本字符和字符串。
(3)将显式数据类型(如BYTE和PBYTE)用于字节、字节指针和数据缓存。
(4)将TEXT宏用于原义字符和字符串。
(5)执行全局性替换(例如用PTSTR替换PSTR)。

6.如何判断一个文本文件是ANSI还是Unicode
判断如果文本文件的开头两个字节是0xFF和0xFE,那幺就是Unicode,否则是ANSI。

7.如何在UnicodeANSI之间转换字符串?

Windows函数MultiByteToWideChar用于将多字节字符串转换成宽字符串;函数WideCharToMultiByte将宽字符串转换成等价的多字节字符串。

另外两个常用的函数(如果出现转换汉文的话请使用setlocale(LC_ALL, "chs");):

size_t mbstowcs( wchar_t *wcstr, const char *mbstr, size_tcount);

size_t wcstombs( char *mbstr, const wchar_t *wcstr, size_tcount);

示例程序:

voidC对话框测试Dlg::OnBnClickedButton1()

{

     // TODO: 在此添加控件通知处理程序代码

 

     DWORD   dwNum = 0;

     wchar_t wText[7]  = L"宽字符串示例";//L告示编译器使用两个字节的 unicode字符集

     char    sText[13] = "窄字符串示例";

 

     wchar_t *pwText =NULL;//指向有ASCII转向UNICODE生成的宽字节

     char    *psText =NULL;//指向有UNICODE转向ASCII生成的窄字节


     // 转换一下

     dwNum = MultiByteToWideChar(CP_ACP,0,sText,-1,NULL,0);

     pwText = new wchar_t[dwNum];

     if (!pwText)

     {

         delete[] pwText;

     }

     MultiByteToWideChar(CP_ACP,// ANSI code page

         0,     //

         sText// MBCS字符串

         -1,    //返回UNICODE字符串包括'\0'的长度

         pwText, // UNICODE字符串数组

         dwNum); // UNICODE字符串数组元素个数

     ::MessageBoxW(this->m_hWnd,pwText,L"显示窄转宽字符串",MB_OK);

     delete[] pwText;

 

     dwNum = WideCharToMultiByte(CP_OEMCP,0,wText,-1,NULL,0,NULL,FALSE);

     psText = new char[dwNum];

     if (!psText)

     {

         delete[] psText;

     }

     WideCharToMultiByte (CP_OEMCP,0,wText, -1,psText,dwNum,NULL,FALSE);

     ::MessageBoxA(this->m_hWnd,psText,"显示宽转窄字符串",MB_OK);

     delete[] psText;

}


 

 

8.默认环境

         在VC6中,默认使用MBCS编码,即多字节字符;而VC8、VC7默认的是Unicode编码,实际就是支持大于0x80的ASCII码。这样,一个中文字可以表示为2个字节,GB2312就是这样表示的。

         检测环境的代码:

#ifndefUNICODE

    AfxMessageBox(TEXT("ASCII"));

#else

    AfxMessageBox(TEXT("UNICODE"));

#endif

 9.其他知识点

字符串前面加L表示该字符串是Unicode字符串。
_T是一个宏,如果项目使用了Unicode字符集(定义了UNICODE宏),则自动在字符串前面加上L,否则字符串不变。因此,Visual C++里边定义字符串的时候,用_T来保证兼容性。VC支持ascii和unicode两种字符类型,用_T可以保证从ascii编码类型转换到unicode编码类型的时候,程序不需要修改。

 


0 0