原文:http://www.cnblogs.com/GT_Andy/archive/2011/01/18/1938605.html

一、定义

1、CString:动态的TCHAR数组。它是一个完全独立的类,封装了+等操作符和字符串操作方法。

2、BSTR:专有格式的字符串(需要使用系统函数来操纵)。定义为:typedef OLECHAR FAR* BSTR

3、LPCTSTR:常量的TCHAR指针。定义为:typedef const char* LPCTSTR

二、要点

1、char*:指向ANSI字符数组的指针,其中每个字符占8位(有效数据是除掉最高位的其他七位),它保持

了与传统C/C++的兼容。

2、LPSTR:指向一个以“\0”结尾的ANSI字符数组的指针,可与char*互换使用,它通常在Win32中使用。

其中LP表示长指针(long pointer)。

3、LPCSTR:该数据类型的特性在于它的实例不能被使用它的API函数改变,除此之外与LPSTR等同。其

中C表示常量(CONSTANT)。

4、在Win16下长指针(LP)和短指针(P)有区别,而在Win32下它们是没有区别的,都是32位。

5、TCHAR在采用Unicode方式下编译时为wchar_t,在普通编码方式下编译时位char。

三、Unicode标准

1、为了满足程序代码国际化的需要,业界推出了Unicode标准,它提供了一种简单和一致的表示字符串的

方法,所有字符中的字节都是16位(两个字节)的值,其数量也可以满足几乎世界上所有书面语言字符的

编码需求,开发程序时使用Unicode(类型位wchar_t)是一种被鼓励的做法。

2、LPWSTR和LPCWSTR由此产生,它们的含义类似于LPSTR和LPCSTR,不同的是字符数据wchar_t为

16位,而char却为8位。

四、TCHAR数据类型

TCHAR数据类型是为了实现ANSI和Unicode两种编码的通用而提出来的

1、如果定义了_UNICODE,则声明如下:

typedef wchar_t TCHAR;

2、如果没有定义_UNICODE,则声明如下:

typedef char TCHAR;

这样就可以让CString、LPTSTR和LPCTSTR中的每个字符都是TCHAR类型,而不考虑它们的编码格

式。而且CString是一个封装好了的类,更是大大地方便了用户的使用。

五、VC++中常用数据类型之间的转换

1、定义

int i=100;

long l=2001;

float f=300.2;

double d=12345.119

char username[]="2008北京奥运";

char temp[200];

char* buf;

CString str;

_variant_t v1;

_bstr_t v2;

2、其他数据类型到字符串的转换

(1)短整形int->字符串

itoa(i,temp,10); //按十进制把i转换为字符串存入temp中

itoa(i,temp,2); //按二进制把i转换为字符串存入temp中

(2)长整形long->字符串

ltoa(l,temp,10);

3、从其他包含了字符串的变量中获取指向该字符串的指针

(1)从CString变量中获取字符串

str="祈福四川";

buf=(LPSTR)(LPCTSTR)str;

(2)从BSTR类型的_varitant_t变量中获取字符串

v1=(_bstr_t)"程序员";

buf=_com_util::ConvertBSTRToString((_bstr_t)v1);

4、字符串转换为其他数据类型

strcpy(temp,"123");

(1)i=atoi(temp); //字符串->短整型int

(2)l=atol(temp); //字符串->长整形long

(3)d=atof(temp); //字符串->浮点型double

5、其他数据类型转换到CString

(1)使用CString的成员函数Format来转换

A:str.Format("%d",i); //短整型int->CString

B:str.Format("%f",f); //浮点数float->CString

(2)支持CString构造函数的数据类型可以直接赋值,例如char*

str=username;

六、BSTR、_bstr_t和CCombBSTR

BSTR:指向字符串的32位指针,_bstr_t和CComBSTR都是对它的封装。

1、char*->BSTR的转换

BSTR b=_com_util::ConvertStringToBSTR("数据");

注:使用之前需要加上comutil.h头文件

2、BSTR->char*的转换

char* p=_com_util::ConvertBSTRToString(b);

七、VARIANT、_variant_t和COleVariant

1、对于VARIANT变量的赋值:首先给vt成员赋值,指明数据类型。再对联合结构中相同数据类型的变量赋

值(可参考VC98\Inlude\OAIDL.H头文件中关于tagVARIANT结构体的定义)。举例如下:

VARIANT va;

va.vt=VT_l4; //指明数据类型

va.lVal=2008;

2、对于不马上赋值的VARIANT,最好先使用void VariantInit(VARIANTARG FAR* pvarg)函数对其进行初始

化,其本质是将vt设置为VT_EMPTY。vt与常用数据类型的对应关系(略)。

3、_variant_t是VARIANT的封装类,赋值可以使用强制类型转换,其构造函数会自动处理这些数据类型。

例如:

long l=222;

int i=100;

_variant_t lVal(l);

lVal=(long)i;

4、COleVariant与_variant_t的使用方法基本一样,示例如下:

COleVariant v3="字符串",v4=(long)1999;

CString str=(BSTR)v3.pbstrVal;

long l=v4.lVal;

八、其他

1、对消息的处理中,我们通常需要将WPARAM或LPARAM等32位数据(DWORD)分解成两个16位数据

(WORD),例如:

LPARAM lParam;

WORD loValue=LOWORD(lParam); //取低16位

WORD hiValue=HIWORD(lParam); //取高16位

2、对于16位的数据(WORD),我们可以使用同样的方法分解成高低两个8位的数据(BYTE),例如:

WORD wValue;

BYTE loValue=LOBYTE(wValue); //取低8位

BYTE hiValue=HIBYTE(wValue); //取高8位

3、如何将CString类型的变量赋给char*类型的变量

(1)CString::GetBuffer函数

char* p;

CString str="hello";

p=str.GetBuffer(str.GetLength());

str.ReleaseBuffer();

(2)strcpy函数

CString str("aaaaaaaa");

strcpy(str.GetBuffer(10),"aa");

str.ReleaseBuffer();

GetBuffer(int n)函数用于获取字符数组,其中n表示字符数组的长度,使用完该字符数组之后一定要调用

ReleaseBuffer()函数来释放这个字符数组。

注:在能够使用const char*的地方,通常不要使用char*

(3)memcpy函数

CString mCS=_T("cxl");

char mch[20];

memcpy(mch,mCS,20);

(4)LPCTSTR强制类型转换(不建议使用)

char* ch;

CString str;

ch=(LPSTR)(LPCTSTR)str;

str="good!";

sprintf(ch,"%s",(LPTSTR)(LPCTSTR)str);

(5)CString->LPTSTR->char*

CString Msg;

Msg=Msg+"abc";

LPTSTR lpsz;

lpsz=new TCHAR[Msg.GetLength()+1];

_tcscpy(lpsz,Msg);

char* psz;

strcpy(psz,lpsz);

4、如何将CString类型的变量赋给const char*类型的变量

char* a[100];

CString str("abcdef");

strncpy(a,(LPCTSTR)str,sizeof(a));

strncpy(a,str,sizeof(a));

注:编译器会自动将CString类型的变量转换为const char*类型

5、如何将CString类型的变量赋给LPCTSTR类型的变量

CString cStr;

const char* lpctStr=(LPCTSTR)cStr;

6、如何将LPCTSTR类型的变量赋给CString类型的变量

LPCTSTR lpctStr;

CString cStr=lpctStr;

7、如何将char*类型的变量赋给CString类型的变量

(1)直接赋值:CString myString="This is a test";

(2)构造函数:CString s1("Tom");

8、如何将CString类型的变量赋给char[](字符串)类型的变量

(1)sprintf函数

CString str="good!";

char temp[200];

sprintf(temp,"%s",(LPCSTR)str);

注:强制类型转换(LPCSTR)str与(LPTSTR)(LPCTSTR)str等同,使用的区别仅在于CString对象是变量

还是常量。LPCTSTR表示const char*,它得到的字符串是不可写的!如果将其强制转换位LPTSTR(去

掉const),是极为危险的!要得到char*,应该使用GetBuffer或GetBufferSetLength函数,用完之后再调

用ReleaseBuffer函数。

(2)strcpy函数

CString str;

char c[256];

strcpy(c,str);

str="Hello";

strcpy((char*)&c,(LPCTSTR)str);

九、关于CString的使用

1、指定CString形参

(1)对于大多数需要字符串参数的函数,最好将函数原型中的形参指定为一个指向字符(LPCTSTR),而非

CString的const指针。当将形参指定为指向字符的const指针时,可将指针传递到TCHAR数组(如字符串["hi

here"]或传递到CString对象)。CString对象将自动转换成LPCTSTR。任何能够使用LPCTSTR的地方也能

够使用CString对象。

(2)如果某个形参将不会被修改,则也将该参数指定为常量字符串引用(const CString&)。如果函数要修改

该字符串,则删除const修饰符。如果需要默认为空值,则将其初始化为空字符串([""]),如下所示:

void AddCustomer(const CString& name,const CString& address,const CString& comment="");

(3)对于大多数函数的结果,按值返回CString对象即可。

2、串的基本运算

char s1[20]="dir/bin/appl",s2[20]="file.asm",s3[30],*p;

int result;

(1)求串长

int strlen(char* s); //求串s的长度

例:printf("%d",strlen(s1));

(2)串复制

char* strcpy(char* to,char* from); //将from串复制到to串中,并返回to开始处的指针

例:strcpy(s3,s1);

(3)串联接

char* strcat(char* to,char* from); //将from串复制到to串的末尾

例:strcat(s3,"/");

strcat(s3,s2);

(4)串比较

int strcmp(char* s1,char* s2); //比较s1和s2的大小,s1<s2(小于0)、s1=s2(0)和s1>s2(大于0)

例:result=strcmp("baker","Baker"); //大于0

result=strcmp("12","12");            //等于0

result=strcmp("Joe","joseph");    //小于0

(5)字符定位

char* strchr(char* s,char c); //找c在字符串s中第一次出现的位置。若找到,则返回该位置;否则NULL。

例:p=strchr(s2,'.'); //p指向"file"之后的位置

(6)注意

A:上述操作是最基本的,其中后4个操作还有变种形式:strncpy、strncath和strnchr。

B:其他的串操作见C的<string.h>头文件。在不同的高级语言中,对串运算的种类及符号都不尽相同。

C:其余的串操作一般可由这些基本操作组合而成。

例:求子串的操作可如下实现

//s和sub是字符数组,用sub返回串s的第pos个字符长度为len的子串

void substr(char* sub,char* s,int pos,int len)

{

//其中0<=pos<=strlen(s)-1,且数组sub至少可容纳len+1个字符

if(pos<0 || pos>strlen(s)-1 ||len<0)

Error("parameter error!");

//从s[pos]起复制至多len个字符到sub

strncpy(sub,*s[pos],len);

}

【转载】CString、BSTR和LPCTSTR之间的区别的更多相关文章

  1. [转载]MCU DSP ARM 嵌入式 之间的区别

    2016-06-28 10:31:24) 嵌入式"这是个概念,准确的定义没有,各个书上都有各自的定义.但是主要思想是一样的,就是相比较PC机这种通用系统来说,嵌入式系统是个专用系统,结构精简 ...

  2. Ubuntu桌面版本和服务器版本之间的区别(转载)

    转载自:http://blog.csdn.net/fangaoxin/article/details/6335992 http://www.linuxidc.com/Linux/2010-11/297 ...

  3. TCP/IP和UDP之间的区别(转载)

    在分析两者之间的区别之前,我们先搞清楚这两者的关系, TCP/IP协议簇  是一种网络控制协议,简单点说就是一种网络协议,我们网络中的计算机就是通过这套协议簇来进行数据通信的.这套协议簇里面包含了很多 ...

  4. 【转载】python3.0与2.x之间的区别

    python3.0与2.x之间的区别: 1.性能 Py3.0运行pystone benchmark的速度比Py2.5慢30%.Guido认为Py3.0有极大的优化空间,在字符串和整形操作上可以取得很好 ...

  5. git fetch和git pull之间的区别--转载

    原文地址:http://blog.csdn.net/a19881029/article/details/42245955 git fetch和git pull都可以用来更新本地库,它们之间有什么区别呢 ...

  6. http、TCP/IP协议与socket之间的区别(转载)

    http.TCP/IP协议与socket之间的区别  https://www.cnblogs.com/iOS-mt/p/4264675.html http.TCP/IP协议与socket之间的区别   ...

  7. socket编程中write、read和send、recv之间的区别~转载

    socket编程中write.read和send.recv之间的区别   http://blog.csdn.net/petershina/article/details/7946615 一旦,我们建立 ...

  8. 【转载】 LSTM构建步骤以及static_rnn与dynamic_rnn之间的区别

    原文地址: https://blog.csdn.net/qq_23981335/article/details/89097757 --------------------- 作者:周卫林 来源:CSD ...

  9. (转)CString,int,string,char*之间的转换

    CString,int,string,char*之间的转换http://www.cnblogs.com/greatverve/archive/2010/11/10/cstring-int-string ...

随机推荐

  1. npm私有仓库搭建

    背景 Node.js开发本地项目,有时不同项目之间存在依赖,如果不想把项目发布到npm社区的仓库,则需要有自己本地的仓库. 有些公司采用的是内网开发,很多npm资源无法从内网去下载. sinopia( ...

  2. zabbix图形插件:Graphtree

    目的:为了达图形聚合 参考博文:https://blog.csdn.net/mysunshineto/article/details/80242754 Graphtree由OneOaaS开发并开源出来 ...

  3. blank site teamplate去了哪里?

    在sharepoint 2010包括sharepoint2010以前,有一个模板是blank site template.到了sharepoint2013,突然发现没有了. 再也不能生成基于blank ...

  4. October 03rd 2017 Week 40th Tuesday

    Don't make promises you can't keep. But those are the best kind. 不要许下做不到的承诺,但是我们做不到的承诺往往是最好的. The be ...

  5. webpack react 单独打包 CSS

    webpack react 单独打包 CSS webpack require css的方法,默认会把css 打入到js文件中,加载顺序有问题,如果需要打出独立的css文件 操作步骤: step1: 安 ...

  6. 我的Java之旅——答答租车系统

    今天试着写了一个新的程序,叫做"答答租车系统",是慕课网上的一个综合练习,戳我看原题. 项目要求截图如下: 我的代码(简单粗暴版): Vehicle.java public cla ...

  7. 是否含有RTTI(运行时类型信息)是动态语言与静态语言的主要区别

    运行时类型信息代表类型信息和对内存的操作能力. 运行时类型信息是运行时系统的基础. 类型信息分为编译时类型信息和运行时类型信息两种: 静态语言的类型信息只在编译时使用和保留,在可执行文件中没有类型信息 ...

  8. Centos7配置samba

    Centos7配置samba 1.安装 yum install samba samba-client samba-common -y 2.配置 备份已有配置mv /etc/samba/smb.conf ...

  9. 【Java123】JDBC数据库连接池建立

    需求场景:多SQL任务多线程并行执行 解决方案:建立JDBC数据库连接池,将线程与连接一对一绑定 https://www.cnblogs.com/panxuejun/p/5920845.html ht ...

  10. 预备作业二——有关CCCCC语言(・᷄ᵌ・᷅)

    有关CCCCC语言(・᷄ᵌ・᷅) 下面又到了回答老师问题的时候啦-(・᷄ᵌ・᷅) 有些问题正在深思熟虑中!敬请期待近期的不间断更新! 你有什么技能比大多人(超过90%以上)更好? 针对这个技能的获取你 ...