设为首页 加入收藏

TOP

字符集之Unicode与字符串对象(二)
2014-11-24 00:40:12 来源: 作者: 【 】 浏览:150
Tags:字符集 Unicode 字符串 对象
字符串

WideCharToMultiByte(CP_BIG5,0,pszUni,-1,pszBig5,iLen,NULL,NULL);

TRACE("%s\n",pszBig5);

delete []pszBig5;

delete []pszUni;

3. 建Unicode的VC++项目的一般步骤
1、 在项目设置的“菜单—Project—Settings—C/C++--Preprocessor definitions”中,将_MBCS预处理定义修改为_UNICODE;

2、 在“菜单—Tools—Debug”中,将“Display unicode strings”选项打勾;

3、 除非指定要使用char类型的字符串,否则应该将字符串常量用_T括起来,例如

//修改前 char szBuf[]="Hello!";

//修改后 TCHAR szBuf[]=_T("Hello!");

4、 有些数据类型要进行相应的转换,如

原数据类型

新数据类型

char

TCHAR

char *

LPTSTR

const char *

LPCTSTR

5、 原有字符串处理函数进行相应转换,一般规律为str***转换为_tcs***,例如

原函数

替换后的函数

strlen

_tcslen

strcpy

_tcscpy

strcat

_tcscat

sprintf

_stprintf 注意此处有不同

示例:

/* 转换前

char szBuf[]="Hello!";

char szBuf2[16];

char *pszBuf=szBuf;

const char *pszBuf2=szBuf;

strcpy(szBuf2,szBuf);

int iLen=strlen(szBuf2);

int iLen2=sizeof(szBuf)-1;

sprintf(szBuf2,"str is:%s",szBuf);

*/

//转换后

TCHAR szBuf[]=_T("Hello!");

TCHAR szBuf2[16];

LPTSTR pszBuf=szBuf;

LPCTSTR pszBuf2=szBuf;

_tcscpy(szBuf2,szBuf);

int iLen=_tcslen(szBuf2);

int iLen2=sizeof(szBuf)/sizeof(TCHAR)-1;

_stprintf(szBuf2,_T("str is:%s"),szBuf);

1. MFC的CString类
1.1. CString实现的机制.

CString是通过“引用”来管理串的,象Window内核对象、COM对象等都是通过引用来实现的。而CString也是通过这样的机制来管理分配的内存块。实际上CString对象只有一个指针成员变量,所以任何CString实例的长度只有4字节.即:

int len = sizeof(CString);//len等于4

这个指针指向一个CStringData结构体类型对象的数据区,即从nAllocLength以后开始的区域:

struct CStringData

{

long nRefs; // 引用计数 www.2cto.com

int nDataLength; // 字符串长度

int nAllocLength; // 已分配的缓冲区大小,应该大于或等于字符串长度

// TCHAR data[nAllocLength]

TCHAR* data() // 实际的数据区

{ return (TCHAR*)(this+1); }

};

正因为如此,一个这样的内存块可被多个CString所引用,例如下列代码:

CString str("abcd");

CString a = str;

CString b(str);

CString c;

c = b;

由于有了这些信息,CString就能正确地分配、管理、释放引用内存块。

如果你想在调试程序的时候获得这些信息。可以在Watch窗口键入下列表达式:

(CStringData*)((CStringData*)(this->m_pchData)-1)或

(CStringData*)((CStringData*)(str.m_pchData)-1)//str为指CString实例

正因为采用了这样的好机制,使得CString在大量拷贝时,不仅效率高,而且分配内存少。

1.2. LPCTSTR 与 GetBuffer(int nMinBufLength)

这两个函数提供了与标准C的兼容转换。在实际中使用频率很高,但却是最容易出错的地方。这两个函数实际上返回的都是指针,但它们有区别:

1、LPCTSTR 它的执行过程其实很简单,只是返回引用内存块的串地址。它是作为操作符重载提供的,所以在代码中有时可以隐式转换,而有时却需强制转制。如:

CString str;

const char* p = (LPCTSTR)str;

//假设有这样的一个函数,Test(const char* p); 你就可以这样调用

Test(str);//这里会隐式转换为LPCTSTR

2、GetBuffer(int nMinBufLength) 它与LPCTSTR类似,也会返回一个指针,不过返回的是LPTSTR

3、一般说LPCTSTR转换后只应该当常量使用,或者做函数的入参;而GetBuffer(...)取出指针后,可以通过这个指针来修改里面的内容,或者做函数的入参。为什么呢?也许经常有这样的代码:

CString sBuf2=sBuf;//指向同一个内存块

//{{错误使用方法

char *pszTemp=(char *)(LPCTSTR)sBuf;

pszTemp[1]='Z'; //它会导致sBuf2的值也变化了

//}}错误使用方法

所以LPCTSTR做转换后,你只能去读这块数据,千万别去改变它的内容。

假如我想直接通过指针去修改数据的话,那怎样办呢?就是用GetBuffer(...):

sBuf="TestCString";

sBuf2=sBuf;//指向同一个内存块

//{{正确的使用方法

//它导致sBuf和sBuf2指向不同的内存块

pszTemp=sBuf.GetBuffer(0);//如果不希望缓冲区变大,直接传0就行了

pszTemp[1]='Z';

sBuf.ReleaseBuffer();

//}}正确的使用方法 CString str("abcd");

为什么会这样?其实GetBuffer(20)调用时,它实际上另外建立了一块新内块存,而原来的内存块引用计数也相应减1. 所以执行代码后sBuf与sBuf2是指向了两块不同的地方

首页 上一页 1 2 3 4 5 下一页 尾页 2/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇查看当前系统可用的动态内存(C) 下一篇c语言中输入输出格式集合

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: