CString 类

2015年12月7日 16:55:34

说说 CString 的几个函数。

  • CString 对象在内存中用一个计数器来维持可用缓冲区的大小。
  • 另外,CString 内,GetLength() 获取字符串长度并不是动态计算的,而是在赋值操作后计算并保存在一个 int 变量内的。

CString:GetBuffer() 和 ReleaseBuffer()

GetBuffer() 函数原型

1
2
3
CString::GetBuffer
LPTSTR GetBuffer( int nMinBufLength );
throw( CMemoryException );
  • Return Value

    An LPTSTR pointer to the object’s (null-terminated) character buffer.

  • Parameters

    nMinBufLength - The minimum size of the character buffer in characters. This value does not include space for a null terminator.

  • Remarks

    Returns 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 you use the pointer returned by GetBuffer to change the string contents, you must call ReleaseBuffer before using any other CString member functions.

翻译过来的意思就是:

  • 返回值:一个指向对象的(以空字符结尾的)字符缓冲区的 LPTSTR 指针。

  • 参数:nMinBufLength 字符缓冲区的以字符数表示的最小容量。这个值不包括一个结尾的空字符的空间。

  • 说明:

    此成员函数返回一个指向 CString 对象的内部字符缓冲区的指针。返回的 LPTSTR 不是 const,因此可以允许直接修改 CString 的内容。

    如果你使用由 GetBuffer 返回的指针来改变字符串的内容,你必须在使用其它的 CString 成员函数之前调用 ReleaseBuffer 函数。

GetBuffer() 函数作用及使用范围

对一个 CString 变量,你可以使用的唯一合法转换符是 LPCTSTR,直接转换成非常量指针(LPTSTR-[const] char*)是错误的。正确的得到一个指向缓冲区的非常量指针的方法是调用 GetBuffer() 方法。

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

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

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

在第二个版本中,

  • 当设定的长度小于原字符串长度时,nMinBufLength = nOldLen,该参数会被忽略,不分配内存,指向原 CString;
  • 当设定的长度大于原字符串本身的长度时就要重新分配(reallocate)一块比较大的空间出来。

而调用第一个版本时,应如通过传入0来调用第二个版本一样。

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

最典型的应用就是读取文件:

1
2
3
4
5
6
7
8
9
10
CFile file;
// FILE_NAME 为实现定义好的文件名称
if(file.Open(FILE_NAME,CFile::modeRead))
{
CString szContent;
int nFileLength = file.GetLength();
file.Read(szContent.GetBuffer(nFileLength),nFileLength);
szContent.ReleaseBuffer();
// 取得文件內容放在szContent中,我们之后可以对其操作
}

ReleaseBuffer() 函数原型

1
2
3
4
5
6
7
8
void ReleaseBuffer( int nNewLength = -1 ) 
{
if( nNewLength == -1 )
{
nNewLength = StringLength( m_pszData );
}
SetLength( nNewLength );
}

ReleaseBuffer() 函数作用及使用范围

CString 对象在内存中用一个计数器来维持可用缓冲区的大小,很明显 ReleaseBuffer 的作用就是更新字符串的长度。CString 内,GetLength 获取字符串长度并不是动态计算的,而是读取的某成员变量的值(此成员变量在赋值操作后计算并更新),当通过 GetBuffer 直接修改 CString时,那个 int 变量(记录长度的成员变量)并不可能自动更新,于是便有了 ReleaseBuffer

当你用 ReleaseBuffer 来释放该缓冲区时,如果指定长度参数,则不应该包含结尾的空字符(如果有的话)。建议不指定参数,使用空参数调用,让 ReleaseBuffer 对该缓冲区执行 strlen 来确定它的长度。

在调用 ReleaseBuffer 之后,由 GetBuffer 返回的地址也许就无效了,因为其它的 CString 操作可能会导致 CString 缓冲区被重新分配。如果你没有改变此 CString 的长度,则缓冲区不会被重新分配。当此 CString 对象被销毁时,其缓冲区内存将被自动释放。

示例

下面的例子说明了如何用 CString::GetBufferCString::ReleaseBuffer(最好逐步调试观察值和地址的变化)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#include <afxwin.h>
void main(void)
{
CString s("abcd");

int i = s.GetLength();
printf("%s\n", s);
printf("s length1 is %d\n", i);

LPTSTR p = s.GetBuffer(6);
strcpy( p, "12345");
printf("%s\n", s);
int j = s.GetLength();
printf("s length2 is %d\n", j);
s.ReleaseBuffer();
printf("%s\n", s);
int k = s.GetLength();
printf("s length3 is %d\n", k);

strcpy( p, "a1b2c3"); // 这里新指定的字串若为"a1b2c3e"则会在此中断
printf("%s\n", s);
int m = s.GetLength();
printf("s length4 is %d\n", m);
}

运行结果为:

运行结果

参考:CString的GetBuffer用法CString:GetBuffer和ReleaseBuffer的作用

CString::Format() 函数与格式输入与输出

http://www.cnblogs.com/kent9/archive/2008/12/30/1365389.html