GetBuffer

GetBuffer

GetBuffer,函數功能是獲取指定緩衝區里的內容大小的指針,從而進行修改。

函數說明


GetBuffer :
說明: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
The following example demonstrates the use of CString::GetBuffer.
// example for CString::GetBufferCString s( "abcd" ); #ifdef _DEBUGafxDump << "CString s " << s << "\n";
#endifLPTSTR p = s.GetBuffer( 10 );
lstrcpy( p, _T("Hello") ); // directly access CString buffer
s.ReleaseBuffer( );
#ifdef _DEBUGafxDump << "CString s " << s << "\n";
#endif

注意事項


說明:
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 p = s.GetBuffer( 10 );//定義一個指針指向LPTSTR並接受GetBuffer所返回的地址
lstrcpy( p, _T("Hello") ); // directly access CString buffer//使用Istrcpy將Hello]複製到該buffer中
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的內部屬性,其實也就是頭部信息。