Windows编程中字符串表示

        今天主要总结以下在这几天的学习中遇到的问题,在照搬书上的代码的时候遇到了很多问题,在对字符串进行处理和作为函数参数的时候遇到了很多问题,被一些LPBYTE,LPTSTR,LPCTSTR,LPWSTR,LPCWSTR等搞得头昏脑涨。最后实在受不了,查了半天资料,自己总结如下。个人水平有限,如有错误还望大家多多批评指正。
                (一)关于字符串的编码
    说起字符串就要从字符char讲起。在一开始学C++时,我先很多人都是接触的ASCII码,而且C++似乎默认的也是用ASCII码来存储,我们知道ASCII码有数量有限,因此表示的字符数量也是寥寥。但是ASCII码在字符表示界占据着统治地位。
    
为了扩展表示范围,比如汉字的表示,人们扩展了ASCII码,这种扩展的ASCII码叫作ANSI码,各个国家和地区都自己定义了自己的ANSI码标准,因此导致出现了各种标准GBK,Big5,Shift_JIS等标准。而因为标准不同的原因,在国际交流中也会带来诸多不便。因此ANSI码中也是存在多个字节表示字符的情况。ANSI码表示英文以及普通字符的时候仍然是单字节,在表示汉字的时候会用双字节。个人理解实现了和ASCII码的兼容。
   
     实际上除了ANSI码,更加提倡的是一种叫做UNICODE码的东西,UNICODE码也是一中ASCII码的扩展,它前128个字符也是ASCII码。只不过这种扩展是一种统一的扩展。它统一的表示了汉字,日文,等各种字符。但是UNICODE编码和ASCII码并不兼容,因为UNICODE对任意字符采用双字节表示。
 
    综上所述,现如今有两种编码:ANSI编码以及UNICODE编码。都是来源于ASCII码的扩展。
C++支持这两种编码,一个是我们常见的字符串“hello”,也就是采用ANSI编码的,而还有一种L“hello”是采用的UNICODE编码。不同之处在于UNICODE编码的字符串在表示的时候用一个L“”来包裹,多了一个“L”在前面。
   
那么问题来了,既然有两种不兼容的字符串的表示形式,那么处理这些函数的时候同样也是存在着两套函数。这时候对于程序员来说是痛苦的,要是突然需要改变字符串的表示形式的时候就需要把那些函数一个一个的改过来,这无疑是痛苦的。比如strlenwcslen分别处理的便是ANSIUNICODE编码的字符串。
 
 
              (二)Windows编程中字符和字符串
在这里我们先告一段落,再讲一讲Windows编程里的一些特殊的类型,与我们在C语言中直接用char表示不同。今天只谈字符串,不谈其他的基本类型的数据。
BYTE\TBYTE
CHAR\ TCHAR
   
         这些类型一看便知道是基本字符类型,只不过换成了大写字母。不过注意到后面的两个前面都加上了T,那么加T到底是什么意思呢。在上面我们讲到因为牵扯到两种编码的问题,会拥有两种不同的函数来处理两种不同的编码,这样在需要切换编码方式的时候,工作量无疑是庞大的,因此微软统一了一种特殊的类型TCHAR和TBYTE,什么意思呢。当前的编码要求是UNICODE的时候,TCHAR,TBYTE就采用UNICODE编码,而在ANSI环境下的时候,就要采用ANSI编码。而系统默认一般都是ANSI,只有在开头加一句#define UNICODE的时候才是默认采用UNICODE编码。这样采用哪一种编码形式就由一句#define来决定了,这无疑很方便。
相应的,这种统一的类型对应的也有一套统一处理函数,比如_tsclen()。定义了UNICODE的时候,这个函数等价于wcslen,而没有定义时,就等价于strlen。
 
LPCSTR/LPSTR/PCSTR/
LPCWSTR/LPWSTR/PCWSTR/
LPCTSTR/LPTSTR/PCTSTR 
        再看这几种类型,末尾都是“STR”,所以这个的意思就是字符串。然后看到“STR”前面的各个字母代表的意思。
P   “P”的意思是指针,也就是说这些都是指针类型,类似于C中用char*表示字符串。
L    “L”的意思是long,也就是说这些指针都是long类型的。
C     “C”的意思是const.
这三个字母用于区分以上类型的横向比较,比如说LPCSTR的意思其实就是
const long char*。其他的就是去掉对应字母的意思就好了,不过P是不能去掉的。
那样就不是指针了,直接用CHAR表示就好了。
  然后纵向比较一下,有W和T两个字母。
W     有“W”的意思是这是采用UNICODE编码的一个字符串,而没有W意思就是一个ANSI编码的字符串。
T       “T”上面说字符的时候我们已经说过了,其实就是微软进行的统一,当在UNICODE编码环境下的时候就是UNICODE字符串,    反之就是ANSI编码的字符串。
所以这几种基本类型就是这样的了。
容易出现的错误就是不了解各种类型的含义而调用函数的时候胡乱进行强制类型转换,导致出现乱码,找不到文件位置,等莫名其妙的错误。
比如
在定义一个字符串的时候用的是TCHAR类型的数组,而且开头并没有定义UNICODE编码,所以默认便是ANSI编码的,但是在使用的时候因为某些函数参数要求采用LPCWST(UNICODE编码的字符串),所以使用者根据提示便不管三七二十一直接强制类型转换,确实不会报错了,但是这时候得到的结果就会是一堆乱码,因为同样的数据采用不同的编码方式计算结果肯定不同。
在了解了这些不同数据类型的根本不同以后,应该就可以根据实际情况用正确的方式定义了,就不会出现乱码了。也是我血的教训。最终还是建议采用微软定义的那些数据类型进行书写,然后根据实际情况决定是否采用UNICODE编码。不过根据我的经验来说,好多函数似乎都要求是用UNICODE编码的字符串做参数,所以还是建议按部就班的定义一下UNICODE,毕竟这也是国际提倡的。
            (三)关于char*  char  const char*的区别
       因为一开始就学的C++的原因,所以对C表示字符串的方式很疑惑,今天就顺便再这里总结一下C中字符串的表示的不同,也相当于是解决上面的LPSTR,CHAR,LPCSTR之间的不同,其他两类则是类似。
我们知道在C中定义字符串的时候有两种方式:
一是 char str[]=“Hello world”;
还有一种是char * pstr=“Hello World”;
        这里要深究一下这两者的不同,char str[],实际上是定义了一个字符数组,数组在程序运行的时候是保存在栈里的,而且申请的是栈中一块连续的内存空间。在找str的时候直接就找到了栈中的一块开头叫作str的连续的内存。
          而char *pstr定义的是一个指针,指针本身保存在栈里,它指向的字符串实际上是一个字符常量,而这个常量自然不是存储在栈里的,所以找pstr指示的字符串的时候先是找到pstr在栈中的位置,读取这个指针的值,然后再根据这个值所指向的位置去找字符串。它门的不同也都是基于这一点的。
          所以只要记住这个char*就是一个指针,char[]是一个数组就好了,基于这个原理,就能够理解各种情况下的奇怪的报错或者警告了。
          最后const char*也好理解,就是一个字符串指针常量,一旦定义不能被修改,也就是不能让它指向别的东西。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值