ansi unicode,ansi编码转换unicode

  ansi unicode,ansi编码转换unicode

  最近在学习中总会遇到CString字符串转换成char*的问题。在这里,我将总结一下unicode项目下的字符串处理问题。

  简述Ansi和Unicode及其各自的优缺点:

  它们是两个字符的编码格式,Ansi=窄字节,Unicode=宽字节。Ansi用char格式表示一个字符,占用一个字节的存储空间,最多表示255个字符,表示英文还可以,但对于中文、日文、韩文等语言就不够用了。所以,如果你的程序是Ansi编码的,那么用中文写的程序在日文、韩文等系统上会出现乱码。所以用Unicode,用两个字节来表示一个字符,格式是无符号short,定义为wchar_t格式,这样就可以表示世界上大部分语言了!但是有利也有弊。劣势呢?也就是空间占用增加了一倍,网络传输的数据量也增加了(一倍)。

  摘要:Windows 2000及以后的Xp、2003、Vista、Win7等系统都是使用Unicode从零开始开发的。如果调用任何Windows API函数并向其传递ANSI字符串,则系统将首先将该字符串转换为Unicode,然后将该Unicode字符串传递给操作系统。如果您希望函数返回ANSI字符串,系统将首先将Unicode字符串转换为ANSI字符串,然后将结果返回给您的应用程序。转换这些字符串需要时间和系统内存。Unicode通常用于避免系统转换所消耗的资源。

  不同编码格式下的字符串处理和相互转换:

  人们编程时经常遇到的数据类型:(以下对应的都是一样的)

   Ansi:

  char、char *、const char *

  CHAR 、( PCHAR、PSTR、LPSTR)、LPCSTR

   Unicode:

  wchar_t、wchar_t *、const wchar_t *

  WCHAR 、( PWCHAR、PWSTR、LPWSTR)、LPCWSTR

   T通用型:

  TCHAR 、( TCHAR *、PTCHAR、PTSTR、LPTSTR)、LPCTSTR

  上图,其中:P代表指针,STR代表字符串,L代表长指针,在WIN32平台下可以忽略,C代表const常量,W代表wide wide byte,T代表template,表示通用。使用时,系统会根据当前工程性质进行转换。比如在unicode下,TCHAR实际上是wCHAR_t,否则就定义为char。

  字符串类型对象的定义:

  Ansi:char * pan istr= hello ;

  Unicode:wchar _ t * pUnicodeStr= hello ;

  通用型:TCHAR * pTStr=_ T( hello );或者TCHAR * pTStr=_ TEXT( hello );(_T,_TEXT也是这个意思)

  动态应用内存:TCHAR *pszBuf=新TCHAR[100];

  常用的字符串处理函数,详见MSDN:

  字符串长度:

  Ansi:strlen(char * str);

  Unicode:wcs len(wchar _ t * str);

  通用函数:_ TCS len(TCHAR * str);

  Ansi:int atoi(const char * str);

  Unicode:int _ wtoi(const wchar _ t * str);

  通用函数:_tstoi(常量TCHAR * str);

  字符串副本:

  Ansi:strcpy(char * strDestination,const char * strSource);

  Unicode:wcs cpy(wchar _ t * strDestination,const wchar _ t * strSource);

  通用函数:_ tcscpy (tchar * strdestination,consttchar * strsource);

  以上函数不安全,在vs2003及以上版本的编译器中会有警告提示。以下是安全函数(vc 6.0不支持):

  Ansi:strcpy _ s(char * strDestination,size_t numberOfElements,const char * strSource);

  Unicode:wcs cpy _ s(wchar _ t * strDestination,size_t numberOfElements,const wchar _ t * strSource);

  通用函数:_ tcscpy _ s (tchar * strdestination,size _ t元素个数,consttchar * strsource);

  元素数量

  目标字符串缓冲区的大小。目标缓冲区的大小,单位是字节,不是字符!

  Size_t无符号整数,MSDN解释:sizeof运算符的结果,也就是说size _ t是无符号整数,即无符号整数。那为什么会有size_t这种类型?

  因为int/long等不同类型的操作系统(32/64)占用的字节数是不一样的,而size_t在不同的平台有不同的定义。有点像TCHAR类型:

  #ifndef _SIZE_T_DEFINED

  #ifdef _WIN64

  typedef unsigned _ _ int 64 size _ t;//8个字节,64位

  #否则

  typedef _W64无符号int size _ t;//4个字节,32位

  #endif

  #定义大小T定义

  #endif

  ANSI和Unicode字符串类型之间的转换:

  上面说的窄字节都是窄字节,宽字节都是宽字节,下面是它们之间的转换。

  在程序中,仍然不建议您来回转换字符串编码,使用Ansi或Unicode。

  但有些API函数往往只提供窄字节版本(如GetProcAddress,见MSDN)或宽字节版本(如CommandLineToArgvW,见MSDN)。

  这时候就需要转换字符串编码格式了。

  不过要提醒一下,并不是所有的都需要转换,有些是不需要的,比如socket中的send或者recv函数。

  =================================================

  字符串占用的字节数:

   Ansi:

  char sztr[]= ABC ;

  占用字节数:sizeof(sztr);

  char * psz= defgh

  求占用字节数:strlen(PSZ)* sizeof(char);

   Unicode:

  wchar _ t szwStr[]=L ABC ;

  占用字节数的计算:sizeof(szwStr);

  wchar _ t * pwsz=L defgh

  占用字节数:wcs len(pwsz)* sizeof(wchar _ t);

  一般功能:

  TCHAR sztr[]=_ T( ABC );

  占用字节数:sizeof(sztr);

  TCHAR * PSZ=_ T( defgh );

  求占用字节数:_ TCS len(PSZ)* sizeof(TCHAR);

  =======================================================

  转换中使用的最基本的API函数:

  WideCharToMultiByte实现宽字节到窄字节的转换。

  MultiByteToWideChar将窄字节转换为宽字节。

  T2W、W2A、T2A和T2W宏的使用和注意事项:

  实际上,这些宏基本上都使用了上述两个函数。

  [1],这些函数都在堆栈中分配空间。例如:A2W(abc ),将在堆栈中分配一块内存来存储 abc

  [2]在使用上述宏之前,使用USES_CONVERSION宏。

  *unicode下CString和char*之间的转换;

  将CString转换为char*:使用wcstombs()函数

  示例:

  CString字符串;

  Str=你好,你好;

  char ch[50];

  wcstombs(ch,str,siez of(ch));

  这种转换会产生问题,因为str有汉字。如果在setlocale(LC_ALL,)包含中文字符之前使用了它,则应该包含头文件locale.h来设置默认语言。

  Char*到CString:使用A2T()函数:

  示例:

  USES _ CONVERSION

  char ch[5]= what ;

  CString字符串;

  str=A2T(ch);

  更常用的调用方式可以百度知道。

ansi unicode,ansi编码转换unicode