`
educast
  • 浏览: 29578 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

GetBuffer与ReleaseBuffer的用法,CString剖析

 
阅读更多

GetBuffer()主要作用是将字符串的缓冲区长度锁定,releaseBuffer则是解除锁定,使得CString对象在以后的代码中继续可以实现长度自适应增长的功能。

CString ::GetBuffer有两个重载版本:

LPTSTR GetBuffer( );LPTSTR GetBuffer(int nMinBufferLength);

在第二个版本中,当设定的长度小于原字符串长度时,nMinBufLength = nOldLen,该参数会被忽

略,不分配内存,指向原CString;当设定的长度大于原字符串本身的长度时就要重新分配(reallocate)一块比较大的空间出来。而调用第一个版本时,应如通过传入0来调用第二个版本一样。

是否需要在GetBufer后面调用ReleaseBuffer(),是根据你的后面的程序是否需要继续使用该字符串变量,并且是否动态改变其长度而定的。如果你GetBuffer以后程序自函数就退出,局部变量都不存在了,调用不调用ReleaseBuffer没什么意义了。

这是一个非常容易被用错的函数,主要可能是由于大家对它的功能不太了解。其实点破的话,也不是那么深奥。
    GetBuffer(int size)是用来返回一个你所指定大小可写内存的成员方法。它和被重载的操作符LPCTSTR还是有点本质区别的,LPCTSTR是直接返回一个只读内存的指针,而GetBuffer则是返回一个可以供调用者写入的内存,并且,你可以给定大小。下面是个简单的,但也是非常典型的例子:
    int readFile(CString& str, const CString& strPathName)
    {
        FILE* fp = fopen(strPathName, "r"); // 打开文件
        fseek(fp, 0, SEEK_END);
        int nLen = ftell(fp); // 获得文件长度
        fseek(fp, 0, SEEK_SET); // 重置读指针
        char* psz = str.GetBuffer(nLen);
        fread(psz, sizeof(char), nLen, fp); //读文件内容
        str.ReleaseBuffer(); //千万不能缺少
        fclose(fp);
    }
    上面的函数是GetBuffer函数最典型的用法了,其实它就相当于申请一块nLen大小的内存,只不过,这块内存是被引用在CString对象的内部而已,这是非常有效的一种用法,如果不直接用GetBuffer函数来申请的话,那么你必须用new操作符(或者malloc()函数)在CString的外部申请,然后再将申请的内存拷贝到CString对象中,显然这是一个非常冗余的操作,会使你函数的效率大大下降。
    ReleaseBuffer函数是用来告诉CString对象,你的GetBuffer所引用的内存已经使用完毕,现在必须对它进行封口,否则 CString将不会知道它现在所包含的字符串的长度,所以在使用完GetBuffer之后,必须立即调用ReleaseBuffer函数重置 CString的内部属性,其实也就是头部信息。

 

补充一下:

GetBuffer说白了就两个功能:

1:就是将CString里面的内存交到外部一个来处理,外部可以直接修改它的内容。

2:重新修改CString的内存大小,这个数值不包含null结尾符。

另一个典型的用法:就是将CString里面的内容变为int或long型,需要先获取里面的内存指针。这样就可以先GetBuffer(内存大小)方便直接转换。

如果在外部修改了CString里面的内容,在重新使用CString之前,需调用ReleaseBuffer()也就是说,ReleaseBuffer不需要每次都调用。

MSDN原文:

If you use the pointer returned by GetBuffer to change the string contents, you must call ReleaseBuffer before using any other CSimpleStringT member methods.

The buffer memory is automatically freed when the CSimpleStringT object is destroyed.

If you keep track of the string length yourself, you should not append the terminating null character. You must, however, specify the final string length when you release the buffer with ReleaseBuffer. If you do append a terminating null character, you should pass –1 (the default) for the length to ReleaseBuffer, and ReleaseBuffer will perform a strlen on the buffer to determine its length.

分享到:
评论

相关推荐

    CString实现的源代码

    CString可以说是MFC中非常有用的类了,因为它可以让我们更加轻松地处理字符串。与其看别人怎么用CSring,...我基本上把CString中常用的函数都看了一遍,像GetBuffer,ReleaseBuffer,AllocBuffer等等,感觉受益匪浅。

    CString操作大全指南

    CString 转化成 char* 之二:使用String对象的GetBuffer方法;CString 转化成 char*之三;和控件的接口;CString 型转化成 BSTR 型;BSTR 型转化成 CString 型;VARIANT 型转化成 CString 型;载入字符串表资源;...

    CString,string,char*之间的转换

    CString 可能是 CStringW/CStringA,在与 string 转换时,如果是 CStringW,还涉及编码转换问题。下面以 CStringA 来说明。 1 string to CString CString.format("%s",string.c_str()); CStringA = string.c_...

    一个跨平台的CString源码

    // make it as forgiving as CString's version is. Thanks to // Igor Kholodov for noticing this. // - Added a specialization of std::swap for CStdString. Thanks // to Mike Crusader for ...

    CString_int_string_char之间的转换

    CString,int,string,char*之间的转换 string 转 CString CString.format(”%s”, string.c_str()); char 转 CString CString.format(”%s”, char*); char 转 string ...string s(CString.GetBuffer());

    MFC 数据类型转换

    1、CString to char* 经过类型强制转换,可以将 CString 类型转换成 char*,例如: CString cStr = "Hello,world!"; char* zStr = (char*)(LPCTSTR)cStr; 2、char* to CString char*类型可以直接给 CString,...

    VC++类型转换整理(PDF格式)

    1、CString to char* 经过类型强制转换,可以将CString类型转换成char*,例如: CString cStr = "Hello,world!"; char* zStr = (char*)(LPCTSTR)cStr; 2、char* to CString char*类型可以直接给CString,完成自动...

    C++日志模块DLL,源码

    void WriteLog(int loglevel, CString strlogstr, CString strfilename, int iline, CString strfunname) { CString g_logdllpath(".\\LoggingModeDLL.dll"); HINSTANCE hDll = LoadLibrary(g_logdllpath....

    FileRename批量重命名工具20190330_1827.7z

    (前缀使用:刘杨-商业修图教程。下同) 首先干掉必须是BMP扩展名! //开始批量重命名文件 void CFileRenameDlg::OnBtStart() { CFileFind flFind; CString szDir; m_FileDir.GetWindowText(szDir); flFind....

    MFC文件操作

    临时文件的使用方法基本与常规文件一样,只是文件名应该调用函数GetTempFileName()获得。它的第一个参数是建立此临时文件的路径,第二个参数是建立临时文件名的前缀,第四个参数用于得到建立的临时文件名。得到此...

    一个简单的注册表操作类,c++

    使用说明: HKEY hKey; LPCTSTR lpSubkey=TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"); long ret0=::RegOpenKeyEx(HKEY_LOCAL_MACHINE,lpSubkey,0,KEY_WRITE,&hKey); if(ret0!=ERROR_SUCCESS) ...

    通讯录 vc 数据库

    CString strSQL; int id=atoi(m_ctrlperson.GetItemText(i,0)); CPersonSet m_recordset; CDBVariant varValue; if(i==-1) { MessageBox("请选择一条要修改的记录!","提示",MB_OK|MB_ICONINFORMATION); } ...

    xml文件解析

    关于在J2ee中xml文件的4中解析和在android中的解析详解

    C++ 四舍五入函数

    参考了一些网友的资料,自己动手... formatstr2 = formatstr.GetBuffer(formatstr.GetLength()); sprintf(s,formatstr2 , 3.1415626); float result = atof((LPCTSTR)s); return result; //返回四舍五入后的数 }

    完整文件打包解包

    // //方法一:这种方法效率比较低 // while(nFileSize-->0) // { // char c; // fread(&c,1,1,pFileOri); // fwrite(&c,1,1,pFilePack); // } //方法二:这种方法效率比较高 char *pBuf = new char[nFileSize];...

    计算器 mfc 代码

    3、添加各种按钮的单击事件处理方法的函数 控件名称列表: 主对话框标识:IDD_CALC_DIALOG 关于对话框标识:IDD_ABOUTBOX 编辑框: IDC_EDIT 运算符按钮标识: 加: IDC_BUTTONADD 减: IDC_BUTTONSUBTRACT 乘: ...

    A set of Ado classes.

    使用方法 1、加入以下两个头文件 #include "..\AdoLib\AdoInterface.h" #include "..\AdoLib\Factory.h" 2、使用名字空间 using namespace MyAdoLib; 3、#pragma comment(lib,"AdoLib") 4、测试例子 ////////...

    RSA加密动态链接库Cryptopp32_DLL_Project

    如果你还在找cryto++的动态链接库你可以到官方网站去下载,里面有动态链接库版本,但是不太适合我们的项目,而且里面的示例没有如何把公钥放在一个string内的方法, 而这个项目就有! 具体请看代码吧,但是说明一点,这个原...

    MD5源码头文件和源文件以及使用说明

    使用方法: char tmp[128]=""; //要加密的字符串 unsigned char digest[16];//加密后的中间字符串 char value[350]="";//最终结果 MD5_CTX context; strcpy(tmp,mSpass.GetBuffer(mSpass.GetLength())); MD5Init (&...

    MFC聊天程序代码

    基于数据库的MFC网络聊天程序 CString data1,data2; data1.Format("%d",zh); data1+="$"; data2.Format("%s",cdata); data1+=data2; ::send(tb[l].s,data1.GetBuffer(0),data1.GetLength(),0);

Global site tag (gtag.js) - Google Analytics