秋涛寒色

平生所为,未尝有不可对人言者

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

首先,这是一个字符集的问题。在ANSI字符集中,字符类型是char,在UNICODE字符集中,字符类型是wchar_t,也可以称之为宽字符,宽字符占两个字节。

然后,我们来看一段定义代码:

//winnt.h

typedef char  CHAR;  //8位

typedef wchar_t  WCHAR;  //16位

typedef CHAR  *PCHAR;

typedef CHAR  *PSTR;

typedef CONST CHAR   *PCSTR;

typedef WCHAR  *PWCHAR;

typedef WCHAR  *PWSTR;

typedef CONST WCHAR   *PCWSTR;

 

//重点在这边

#ifdef  UNICODE  //如果使用的事UNICODE字符集,一般来说,VS建立的工程默认都是使用UNICODE字符集

  typedef WCHAR  TCHAR,*PTCHAR,*PTSTR;

  typedef CONST WCHAR   *PCTSTR;

  #define _TEXT(quote)  L##quote

  #define _T(quote)  L##quote

#else

  typedef CHAR  TCHAR,*PTCHAR,*PTSTR;

  typedef   CONST CHAR   *PCTSTR;

  #define  _TEXT(quote)  quote

  #define   _T(quote)   quote

#endif

#define TEXT(quote)  _TEXT(quote)

//下面这句话才是最重要的要记住的!!!

由此可以看出,“C”是指CONST,“T”表示如果使用UNICODE字符集的话就代表是“W”,即宽字符类型,PSTR是指向字符的指针类型,即char*

所以,如果使用UNICODE字符集的话,可以这样理解:

    TCHAR ——> WCHAR

    PCTSTR ——> PCWSTR ——> CONST PWSTR ——> CONST "wide" PSTR ——>const "wide" char* ——>const wchar_t*,同理,PTSTR可以理解成wchar_t*

所以平常用的时候要尽量使用TCHAR,PTSTR,PCTSTR

还有一个“L”,加一个“L”表明通知编译器应该把该字符串编译为一个UNICODE字符串,即字符串里的每个字符使用两个字节来表示,如LPSTR,LPCSTR指向的字符串里的字符都是占两个字节,但是L和T都出现的时候可以去掉其中一个,比如LPTSTR和LPCTSTR,去掉里面的L,就相当于PTSTR和PCTSTR,和原来没什么区别。

 

因为大家都习惯了C语言里的库函数,所以在Windows编程里会常常习惯性的用到,尤其是字符串处理函数,但是编译的时候又会发现错误,又或者编译通过而不能运行。其实原因也很简单,C语言的字符串函数支持的是ANSI字符集,所以我们在Windows编程里不能使用string.h里的字符串函数。建议使用的是头文件tchar.h里面的字符串处理函数,具体处理函数请看下一篇文章。

 

另外,Windows编程里在调用系统接口通常都有两种,如SetWindowText有SetWindowTextA和SetWindowTextW两种,一个支持ANSI字符集,一个支持UNICODE字符集。事实上,ANSI版本的函数的内部只分配内存,然后执行字符串转换,再调用该函数的UNICODE版本。不过平常我们只要用SetWindowText就行了,它的形式和上面的宏定义差不多,如果使用UNICODE字符集则内部用UNICODE版本的函数。

 

《Windows核心编程》这本书中对于Windows中的字符和字符串处理方式推荐:

   1.将字符串当作字符数组看待

   2.使用通用数据类型,如TCHAR,PTSTR等

   3.避免使用prinf系列函数

   4.使用安全的字符串处理函数

   5.用tchar.h中的字符串处理函数

   6.修改与字符串相关的计算,字符串所占的字符数和字节数不一定相同

 

posted on 2015-05-25 20:28  秋涛寒色  阅读(909)  评论(0编辑  收藏  举报