Unicode与Ansi的区别

http://www.cppblog.com/lapcca/archive/2010/05/06/114649.html

Unicode与Ansi是两种不同的编码方式标准,Ansi中的字符采用8bit,而Unicode中的字符采用16bit。

(对于字符,Ansi以单字节存放英文字符,以双字节存放中文等字符;而Unicode下,英文和中文的字符都以双字节存放

Unicode码也是一种国际标准编码,采用二个字节编码,与Ansi码不兼容。目前,在网络、Windows系统和很多大型软件中得到应用。

8bit的ANSI编码只能表示256种字符,表示26个英文字母是绰绰有余的,但是表示汉字等有着成千上万个字符的非西方字符肯定就不够了,正是如此才引入Unicode标准。   

在软件开发中,特别是使用C语言的一些有关字符串处理的函数,Ansi和Unicode是区分使用的,那么Ansi类型的字符和Unicode类型的字符如何定义,如何使用呢?Ansi和Unicode又如何转换呢?

一.定义部分 

Ansi:即char

Unicode:即wchar_t

注意:VC++6.0 默认编码方式为Ansi,.Net默认编码方式为Utf-16,Linux GCC默认编码方式为utf-8

二.可用函数

Ansi:可用字符串处理函数:strcat(),strcpy(),strlen()等以str打头的函数

Unicode:可用字符串处理函数:wcscat(),wcscpy(),wcslen()等以wcs打头的函数。

三.系统支持  

 Windows 98:只支持Ansi   

 Windows 2000/XP/2003:既支持Ansi又支持Unicode

Windows CE:只支持Unicode。

说明:

1> 在COM里面只支持UNICODE。 

2> Windows 2000整个OS系统都是基于Unicode的,为此在windows 2000 下使用ANSI是需要付出代价的,虽然在编码上不用任何的转换,但是这种转化是隐藏的,是占用系统资源的(CPU,内存)    

四.如何区分:   

在我们软件开发中往往需要即支持Ansi又支持Unicode,不可能在要求类型转换的时候,重新改变字符串的类型,和使用于字符串上的操作函数。为此,标准C运行期库和Windows 提供了宏定义的方式。

在C语言里面提供了 _UNICODE宏(有下划线),在Windows里面提供了UNICODE宏(无下划线)

只要定了_UNICODE宏和UNICODE宏,系统就会自动切换到UNICODE版本,否则,系统按照ANSI的方式进行编译和运行。

只定义了宏并不能实现自动的转换,还需要一系列的字符定义支持

1. TCHAR   

如果定义了Unicode宏,则TCHAR被定义为wchar_t。   

typedef    wchar_t    TCHAR;   

否则TCHAR被定义为char   

typedef    char   TCHAR;   

2.LPTSTR   

如果定义了Unicode宏,则LPTSTR被定义为LPWSTR

typedef    LPTSTR   LPWSTR;   

否则TCHAR被定义为char   

typedef    LPTSTR   LPSTR;  

补充一下:

utf -8是可以用于真正的流式传输的,Unicode是一种编码方案   

( utf -8是Unicode的一种具体实现。类似的实现还有utf-16等等 )

三.Ansi/Unicode字符和字符串 

TChar.h是String.h的修改,用于创建Ansi/Unicode通用字符串。

Unicode字符串的每个字符都是16位的。

wchar_t是Unicode字符的数据类型。

附:有部分Unicode函数也可以在Win9X中使用,但可能会出现意想不到错误。

所有的Unicode函数均以wcs开头,Ansi函数均以str开头;ANSI C规定C运行期库支持Ansi和Unicode

Ansi:

#include <string.h>

char * strcat(char *, const char *) 

char * strchr(cons char *, int)

int strcmp(const char *,  const char *) 

char * strcpy(char *, const char *) 

size_t strlen(const char *)                 

Unicode: 

#include <stdlib.h>

wchar_t * wcscat(wchar_t  *, const wchar_t *) 

wchar_t * wcschr(const wchar_t * , int) 

 int  wcscmp(const wchar_t *, const wchar_t *)

wchar_t * wcscpy(wchar_t *, const wchar_t *)

wchar_t wcslen(const wchar_t *)

L" wash " : 用于将ANSI字符串转换为Unicode字符串;

 _TEXT(" wash ")根据是否定义Unicode或_Unicode进行转换。

附:_Unicode用于C运行库;Unicode用于Windows头文件。

ANSI/Unicode通用数据类型:

1> Both(ANSI/Unicode)

LPCTSTR、LPTSTR、PCTSTR、PTSTR、TBYTE(TCHAR)

2> ANSI

LPCSTR、LPSTR、PCSTR、PSTR、CHAR

3> Unicode

LPCWSTR、LPWSTR、PCWSTR、PWSTR、WCHAR  (与ANSI相比,多了' W ')

字符表示意义如下:

L表示long指针、P表示这是一个指针、C表示是一个常量、T表示在Win32环境中, 有一个_T宏、STR表示这个变量是一个字符串

在设计dll时最好提供Anis和Unicode函数,Ansi函数只用于分配内存,将字符转换为Unicode字符,然后调用Unicode函数。

最好使用操作系统函数,少使用或不实用C运行期函数

eg:操作系统字符串函数(shlWApi.h)

StrCat(), StrChr(), StrCmp(), StrCpy()等

注意它们区分大小写,也区分ANSI和Unicode版本

附:Ansi版函数在原函数后加大写字母A

Unicode函数在原函数后加大写字母W

成为符合Ansi和Unicode的函数:

1> 将文本串视为字符数组,而不是chars数组或字节数组

2> 将通用数据类型(如TCHAR和PTSTR)用于文本字符和字符串

3> 将显式数据类型(如BYTE和PBYTE)用于字节、字节指针和数据缓存

4> 将TEXT宏用于原义字符和字符串

5> 修改字符串运算问题 

如:sizeof(szBuffer) -> sizeof(szBuffer) / sizeof(TCHAR)

malloc(charNum) -> malloc(charNum * sizeof(TCHAR)) 

对Unicode字符操作的函数还有:(也有ANSI和Unicode版本)

lstrcat() , lstrcmp() / lstrcmpi()[ 它们在内部调用CompareString() ], lstrcpy(), lstrlen()

这些是作为宏实现的。

C运行期函数

tolower();

toupper();

isalpha();

islower();

isupper();

print();

windows函数

PTSTR   CharLower(PTSTR   pszString);

PTSTR   CharUpper(PTSTR   pszString);

BOOL   IsCharAlpha(TCHAR   ch);

BOOL   ISCharAlphaNumeric(TCHAR   ch);

BOOL   IsCharLower(TCHAR   ch);

BOOL   IsCharUpper(TCHAR   ch);

wsprintf();

转换Buffer:

DWORD   CharLowerBuffer(PTSTR   pszString , DWORD cchString);

DWORD CharUpperBuffer(PTSTR   pszString , DWORD   cchString);

转换单个字符,如:

TCHAR   cLowerCaseChar = CharLower((PTSTR)szString[0]);

确定字符是ANSI或Unicode:

BOOL IsTextUnicode(

const   VOID   * pBuffer,   //待检查的InputBuffer

int   cb,                               //InputBuffer中的长度

LPINT   lpi                         //检查选项

)

附:此函数在Win9x系统中,没有实现代码,始终返回FALSE

五、Unicode与ANSI之间的转换:

( 1 ) 使用宏定义

如下例:

[cpp]  view plain copy
  1. char szA[40];  
  2. wchar szW[40];  
  3. //Normal sprintf: all string are Ansi  
  4. sprintf(szA , "%s""ANSI str");  
  5. //Convert Unicode to ANSI  
  6. sprintf(szA, "%S",  L"Unicode str");  
  7. //Normal swprintf: all string are unicode  
  8. swprinf(szW, "%s", L" Unicode str");  
  9. // Convert ANSI to Unicode  
  10. swprinf( szW, L"%S""Ansi str");  

( 2 ) 使用MultiByteToWideChar()

该函数映射一个字符串到一个宽字符( Unicode )的字符串。

( 3 ) 使用WideCharToMultiByte() 

映射一个宽字符串到一个多字节字符串。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值