CString中GetBuffer函数的应用

来源:互联网 发布:葫芦娃桌面软件 编辑:程序博客网 时间:2024/05/22 10:32
说明:MFC函数
  所属类:CString ,CBookMark,CBaseAllocator
  介绍,CString:GetBuffer;
  MSDN对该函数的解释:
  This method retrieves a pointer to the internal character buffer for the CString object. The returned LPTSTR is not const and thus allows direct modification of CString contents.
  If nMinBufLength is greate than the length of the current buffer, the call to GetBuffer will destroy the current buffer. Replace it with a buffer of the requested size, and reset the reference count to zero. If you have previously called LockBuffer on this buffer, you will lose the lock on the buffer.
  这个函数是为一个CString对象重新获取其内部字符缓冲区的指针,返回的LPTSTR为非const的,从而允许直接修改CString中的内容!如果nMinBufLength 比当前buffer大,那么就调用ReleaseBuffer函数去释放当前的Buffer,用一个被请求的大小去覆盖这个buffer,重新设定计数器为0,如果在这之前你在这个buffer中调用了LockBuffer,那么你将失去你当前锁定的buffer
  说明:
  If you use the pointer returned by GetBuffer to change the string contents, you must call ReleaseBuffer before using any other CString methods. 
  The address returned by GetBuffer may not be valid after the call to ReleaseBuffer since additional CString operations may cause the CString buffer to be reallocated. The buffer will not be reallocated if you do not change the length of the CString.
  The buffer memory will be freed automatically when the CString object is destroyed. 
  Note that, 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 for the length to ReleaseBuffer, which will perform a _tcslen on the buffer to determine its length.
  如果你使用这个指向由GetBuffer所改变返回的字符串内容,那么在你使用CString其他CString方法之前你必须调用ReleaseBuffer
  在调用ReleaseBuffer函数之后GetBuffer中的内容将无效(也就是销毁)
  当这个CString被销毁的时候,这个buffer所占用的内存将被自动释放
  注意这个: 如果你知道了这个字符串的长度,你不可以直接添加NULL字符了事,当你使用ReleaseBuffer的时候你无论如何详细说明字符串的结束位置,如果你仅仅添加了一个NULL字符结束符给这个字符串,你应该给ReleaseBuffer传递一个-1 当这个函数结束的时候_tcslen 将决定这个buffer的长度
  例子:
  // example for CString::GetBuffer
  CString s( "abcd" );//定义一个CString s并且初始化为abcd
  #ifdef _DEBUG
  afxDump << "CString s " << s << "/n";
  #endif

 

       //定义一个指针指向LPTSTR并接受GetBuffer所返回的地址    LPTSTR p = s.GetBuffer( 10 );

       // directly access CString buffer//使用Istrcpy将Hello]复制到该buffer中
  lstrcpy( p, _T("Hello") );
     
  s.ReleaseBuffer( );//释放buffer
 
  #ifdef _DEBUG
  afxDump << "CString s " << s << "/n";这时候s="Hello";
  #endif
  这是一个非常容易被用错的函数,主要可能是由于大家对它的功能不太了解。其实点破的话,也不是那么深奥。
  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的内部属性,其实也就是头部信息。

转自:http://blog.csdn.net/ys_w/article/details/5217732