关于CString总结

合集下载

cstring 分割函数

cstring 分割函数

cstring 分割函数Cstring分割函数是一种非常常用的字符串处理函数,在C++语言中,字符串是一个非常重要的数据类型,因此对于字符串的处理,也是一个需要掌握的技能。

一、Cstring分割函数的基本概念Cstring分割函数的基本概念就是将一个字符串按照指定的分隔符进行分割,得到一个字符串数组。

例如,将一个以空格为分隔符的字符串"hello world"进行分割,得到的字符串数组就是{"hello", "world"}。

二、Cstring分割函数的实现原理Cstring分割函数的实现原理是通过一个循环来遍历整个字符串,判断每个字符是否为分隔符,如果是,则将前面的字符组成一个字符串,并将其存储到字符串数组中。

需要注意的是,最后一个字符串后面可能没有分隔符,因此需要额外处理一下。

具体实现可以参考以下代码:```c++#include <iostream>#include <cstring>using namespace std;int main(){char str[] = "hello world";char *p = strtok(str, " ");while (p != NULL){cout << p << endl;p = strtok(NULL, " ");}return 0;}```三、Cstring分割函数的应用场景Cstring分割函数可以应用于很多场景,比如对于一个用户输入的字符串,需要将其中的单词分离出来,或者对于一个CSV文件,需要将其中的每一行都进行分割,得到一个二维数组。

四、Cstring分割函数的优缺点Cstring分割函数的优点是实现简单,可以快速地将一个字符串分解为若干个子字符串。

缺点是只能处理单个字符作为分隔符,如果需要处理多个字符作为分隔符,就需要进行额外的处理。

CString用法

CString用法

需要强制类型转化时,C++规则容许这种选择。

比如,你可以将(浮点数)定义为将某个复数(有一对浮点数)进行强制类型转换后只返回该复数的第一个浮点数(也就是其实部)。

可以象下面这样:Complex c(1.2f,4.8f);float realpart=c;如果(float)操作符定义正确的话,那么实部的的值应该是1.2。

这种强制转化适合所有这种情况,例如,任何带有LPCTSTR类型参数的函数都会强制执行这种转换。

于是,你可能有这样一个函数(也许在某个你买来的DLL中):BOOL DoSomethingCool(LPCTSTR s);你象下面这样调用它:CString file("c:¥¥myfiles¥¥coolstuff")BOOL result=DoSomethingCool(file);它能正确运行。

因为DoSomethingCool函数已经说明了需要一个LPCTSTR类型的参数,因此LPCTSTR被应用于该参数,在MFC 中就是返回的串地址。

如果你要格式化字符串怎么办呢?CString graycat("GrayCat");CString s;s.Format("Mew!I love%s",graycat);注意由于在可变参数列表中的值(在函数说明中是以"..."表示的)并没有隐含一个强制类型转换操作符。

你会得到什么结果呢?一个令人惊讶的结果,我们得到的实际结果串是:"Mew!I love GrayCat"。

因为MFC的设计者们在设计CString数据类型时非常小心,CString类型表达式求值后指向了字符串,所以这里看不到任何象Format或sprintf中的强制类型转换,你仍然可以得到正确的行为。

描述CString的附加数据实际上在CString名义地址之后。

CString字符串操作函数汇总

CString字符串操作函数汇总

int ReverseFind( TCHAR ch ) const;
从后向前查找第一个匹配,找到时返回下标。没找到时返回-1
例:csStr="abba";
cout<<csStr.ReverseFind('a'); //3
void Format( LPCTSTR lpszFormat, ... );
void MakeLower( );
将大写字母转换为小写字母
例:csStr="ABCDEF中文123456";
csStr.MakeLower();
cout<<csStr; //abcdef中文123456
int Compare( LPCTSTR lpsz ) const;
cout<<csStr.Find('b',0); //1
cout<<csStr.Find("de",4); //-1
cout<<csStr.Find("de",0); //3
//当nStart超出对象末尾时,返回-1。
//当nStart为负数时,返回-1。
CString SpanExcluding( LPCTSTR lpszCharSet ) const;
返回对象中与lpszCharSet中任意匹配的第一个字符之前的子串
例:csStr="abcdef";
cout<<csStr.SpanExcluding("cf"); //ab
csStr.TrimLeft("ab");

VS2010和MFC编程入门之42(MFC常用类:CString类)

VS2010和MFC编程入门之42(MFC常用类:CString类)

VS2010MFC编程入门之四十二(MFC常用类:CString类)理解了分割窗口的有关知识,这里开始讲解MFC的一些常用类,先来说说CString类。

CString类简介CString类作为MFC的常用类,当之无愧。

可以这样说,只要是从事MFC开发,基本都会遇到使用CString类的场合。

因为字符串的使用比较普遍,而CString类又提供了对字符串的便捷操作,所以它给MFC开发人员带来了高的开发效率,受到了开发者的欢迎。

大家使用VS2010的话,可能会见到CStringT,实际上它是一个操作可变长度字符串的模板类。

CStringT模板类有三个实例:CString、CStringA和CStringW,它们分别提供对TCHAR、char和wchar_t字符类型的字符串的操作。

char类型定义的是Ansi字符,wchar_t类型定义的是Unicode字符,而TCHAR取决于MFC工程的属性对话框中的Configuration Properties->General->Character Set属性,如果此属性为Use Multi-Byte Character Set,则TCHAR类型定义的是Ansi字符,而如果为Use Unicode Character Set,则TCHAR类型定义的是Unicode字符。

三个字符串类的操作是一样的,只是处理的字符类型不同。

鸡啄米以CString类为讲解对象。

CString类的字符串操作1. CString类的构造函数CString类有很多构造函数,这里只介绍几个比较常用的:CString(constCString&stringSrc);将一个已经存在的CString对象stringSrc的内容拷贝到该CString对象。

例如:C++代码CString str1(_T("")); // 将常量字符串拷贝到str1 CString str2(str1); // 将str1的内容拷贝到str2CString(LPCTSTR lpch, intnLength);将字符串lpch中的前nLength个字符拷贝到该CString对象。

cstring方法

cstring方法

cstring方法在C++中,字符串是一种非常重要的数据类型,广泛应用于各种场景中。

为了方便处理字符串,C++提供了一些常见的字符串操作函数,其中最常用的就是cstring方法了。

在本篇文章中,我们将详细介绍cstring方法的使用方法。

一、cstring方法概述cstring是C++标准库中定义的一个字符串操作库,包括了各种字符串操作函数,如字符串复制strcpy、字符串合并strcat、字符串长度strlen等。

cstring库有时也称为C-string库,因其支持C风格的字符串操作。

cstring库是头文件<string.h>的一个子集,实际上只包含了C-style字符串(以null字符结尾)的函数操作。

二、使用cstring方法进行字符串复制在C++中,字符串复制是一个非常常用的操作,我们称之为strcpy。

下面是strcpy的使用方法:char str1[] = "Hello, world!";char str2[50];strcpy(str2, str1); // 复制 str1 到 str2cout << "str1: " << str1 << endl;cout << "str2: " << str2 << endl;输出:str1: Hello, world! str2: Hello, world!上面的代码中,我们首先声明了两个字符串,一个是str1,另一个是str2。

然后使用strcpy函数将str1复制到str2中。

最后通过cout语句输出了str1和str2的值。

三、使用cstring方法进行字符串合并字符串合并是另一个常见的操作,我们称之为strcat。

下面是strcat的使用方法:char str1[50] = "Hello";char str2[50] = "World";strcat(str1, str2);cout << "str1: " << str1 << endl;cout << "str2: " << str2 << endl;输出:str1: HelloWorld str2: World在上面的代码中,我们首先声明了两个字符串,然后使用strcat 函数将str2中的内容追加到str1的末尾。

CString的Format方法使用技巧小结

CString的Format方法使用技巧小结

CString的Format方法使用技巧小结CString类是MFC(Microsoft Foundation Classes)中提供的一个用于处理字符串的类,它封装了许多字符串处理的功能,其中包括Format方法。

Format方法可以将格式化的字符串输出到CString对象中,类似于C语言中的printf函数。

在本文中,我将总结一些使用CString的Format方法的技巧。

1.格式化字符串中的占位符:在格式化字符串中,可以使用占位符来表示需要被替换的值。

常用的占位符有:%d(整数)、%f(浮点数)、%s(字符串)、%c(字符)等。

例如:````str.Format("The value is %d", 10);```输出的结果为:"The value is 10"。

2.多个占位符:在格式化字符串中,可以使用多个占位符来表示多个需要被替换的值。

例如:````str.Format("The values are %d and %d", 10, 20);```输出的结果为:"The values are 10 and 20"。

3.格式化字符串中的转义字符:在格式化字符串中,可以使用转义字符来表示一些特殊字符。

常用的转义字符有:\n(换行符)、\t(制表符)、\\(反斜杠)等。

例如:````str.Format("This is a newline\nThis is a tab\tThis is a backslash\\");```输出的结果为:````This is a newlineThis is a tab This is a backslash\```4.格式化字符串中的宽度和精度:在格式化字符串中,可以使用宽度和精度来控制输出的格式。

宽度表示输出的最小字符数,精度表示浮点数的小数位数。

例如:```````输出的结果为:"The value is 3.14"。

Cstring字符串比较方法详解

Cstring字符串比较方法详解

Cstring字符串比较方法详解字符串可以和类型相同的字符串相比较,也可以和具有同样字符类型的数组比较。

Basic_string 类模板既提供了 >、<、==、>=、<=、!= 等比较运算符,还提供了 compare() 函数,其中 compare() 函数支持多参数处理,支持用索引值和长度定位子串进行比较。

该函数返回一个整数来表示比较结果。

如果相比较的两个子串相同,compare() 函数返回0,否则返回非零值。

compare()函数类 basic_string 的成员函数 compare() 的原型如下:int compare (const basic_string& s) const;int compare (const Ch* p) const;int compare (size_type pos, size_type n, const basic_string& s) const;int compare (size_type pos, size_type n, const basic_string& s,size_type pos2, size_type n2) const;int compare (size_type pos, size_type n, const Ch* p, size_type = npos) const;如果在使用compare() 函数时,参数中出现了位置和大小,比较时只能用指定的子串。

例如:pare {pos,n, s2);若参与比较的两个串值相同,则函数返回0;若字符串S 按字典顺序要先于S2,则返回负值;反之,则返回正值。

下面举例说明如何使用 string 类的 compare() 函数。

【例 1】复制纯文本复制1.#include <iostream>2.#include <string>3.u sin g namespace std;4.int main ()5.{6.string A ('aBcdef');7.string B ('AbcdEf');8.string C ('123456');9.string D ('123dfg');10.//下面是各种比较方法11.int m=pare (B); //完整的A和B的比较12.int n=pare(1,5,B,4,2); //'Bcdef'和'AbcdEf'比较13.int p=pare(1,5,B,4,2); //'Bcdef'和'Ef'比较14.int q=pare(0,3,D,0,3); //'123'和'123'比较15.cout << 'm = ' << m << ', n = ' << n <<', p = ' << p << ', q = ' << q << endl;16.cin.get();17.return 0;18.}#include <iostream> #include <string> u sin g namespace std; int main () { string A ('aBcdef'); string B ('AbcdEf'); string C ('123456'); string D ('123dfg'); //下面是各种比较方法int m=pare (B); //完整的A和B的比较int n=pare(1,5,B,4,2); //'Bcdef'和'AbcdEf'比较int p=pare(1,5,B,4,2); //'Bcdef'和'Ef'比较int q=pare(0,3,D,0,3); //'123'和'123'比较 cout << 'm = ' << m << ', n = ' << n <<', p = ' << p << ', q = ' << q << endl; cin.get(); return 0; }程序的执行结果为:m = 1, n = -1, p = -1, q = 0由此可知,string 类的比较 compare() 函数使用非常方便,而且能区分字母的大小写。

cstring头文件例题

cstring头文件例题

cstring头文件例题摘要:一、CString头文件简介1.CString的定义2.CString与字符串的关系3.CString头文件的包含二、CString常用函数1.CString的构造函数2.CString的拷贝构造函数3.CString的赋值函数4.CString的连接函数5.CString的查找函数6.CString的替换函数7.CString的比较函数8.CString的长度函数9.CString的访问与修改三、CString应用实例1.CString的简单应用2.CString的复杂应用正文:CString头文件是C++编程中经常使用的一个头文件,它提供了C++中字符串的操作功能。

CString是C++中的一种字符串类型,它与C语言中的字符串有所不同,CString可以动态地分配和释放内存,同时可以对字符串进行操作。

一、CString头文件简介CString的定义在CString头文件中,它是一种模板类,定义如下:```cpptemplate <class T>class CString {public:CString();CString(const T* psz);CString(const CString& str);~CString();CString& operator=(const CString& str);CString& operator=(const T* psz);int GetLength() const;void Release();void Attach(const T* psz);const T* GetBuffer() const;T* GetBuffer(size_t nLength);private:T* m_pch;int m_nLength;int m_nMaxLength;};```CString与字符串的关系是CString是字符串的一种实现方式,它可以动态地分配和释放内存,同时可以对字符串进行操作。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

关于CString总结作者:wangshengxiang前言:串操作是编程中最常用也最基本的操作之一。

做为VC程序员,无论是菜鸟或高手都曾用过Cstring。

而且好像实际编程中很难离得开它(虽然它不是标准C++中的库)。

因为MFC中提供的这个类对我们操作字串实在太方便了,CString不仅提供各种丰富的操作函数、操作符重载,使我们使用起串起来更象basic中那样直观;而且它还提供了动态内存分配,使我们减少了多少字符串数组越界的隐患。

但是,我们在使用过程中也体会到CString简直太容易出错了,而且有的不可捉摸。

所以有许多高人站过来,建议抛弃它。

在此,我个人认为:CString封装得确实很完美,它有许多优点,如“容易使用,功能强,动态分配内存,大量进行拷贝时它很能节省内存资源并且执行效率高,与标准C完全兼容,同时支持多字节与宽字节,由于有异常机制所以使用它安全方便”其实,使用过程中之所以容易出错,那是因为我们对它了解得还不够,特别是它的实现机制。

因为我们中的大多数人,在工作中并不那么爱深入地去看关于它的文档,何况它还是英文的。

由于前几天我在工作中遇到了一个本不是问题但却特别棘手、特别难解决而且莫名惊诧的问题。

好来最后发现是由于CString引发的。

所以没办法,我把整个CString的实现全部看了一遍,才慌然大悟,并彻底弄清了问题的原因(这个问题,我已在csdn上开贴)。

在此,我想把我的一些关于CString的知识总结一番,以供他(她)人借鉴,也许其中有我理解上的错误,望发现者能通知我,不胜感谢。

1. CString实现的机制.CString是通过“引用”来管理串的,“引用”这个词我相信大家并不陌生,象Window内核对象、COM对象等都是通过引用来实现的。

而CString也是通过这样的机制来管理分配的内存块。

实际上CString对象只有一个指针成员变量,所以任何CString实例的长度只有4字节.即: int len = sizeof(CString);//len等于4这个指针指向一个相关的引用内存块,如图: CString str("abcd");‘A’‘B’‘C’‘D’0x04040404 head部,为引用内存块相关信息str 0x40404040正因为如此,一个这样的内存块可被多个CString所引用,例如下列代码:CString str("abcd");CString a = str;CString b(str);CString c;c = b;上面代码的结果是:上面四个对象(str,a,b,c)中的成员变量指针有相同的值,都为0x40404040.而这块内存块怎么知道有多少个CString引用它呢?同样,它也会记录一些信息。

如被引用数,串长度,分配内存长度。

这块引用内存块的结构定义如下:struct CStringData{long nRefs; //表示有多少个CString 引用它. 4int nDataLength; //串实际长度. 4int nAllocLength; //总共分配的内存长度(不计这头部的12字节). 4};由于有了这些信息,CString就能正确地分配、管理、释放引用内存块。

如果你想在调试程序的时候获得这些信息。

可以在Watch窗口键入下列表达式:(CStringData*)((CStringData*)(this->m_pchData)-1)或(CStringData*)((CStringData*)(str.m_pchData)-1)//str为指CString实例正因为采用了这样的好机制,使得CString在大量拷贝时,不仅效率高,而且分配内存少。

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) 它类似,也会返回一个指针,不过它有点差别,返回的是LPTSTR(3) 这两者到底有何不同呢?我想告诉大家,其本质上完全不一样,一般说LPCTSTR转换后只应该当常量使用,或者做函数的入参;而GetBuffer(...)取出指针后,可以通过这个指针来修改里面的内容,或者做函数的出参。

为什么呢?也许经常有这样的代码:CString str("abcd");char* p = (char*)(const char*)str;p[2] = 'z';其实,也许有这样的代码后,你的程序并没有错,而且程序也运行得挺好。

但它却是非常危险的。

再看CString str("abcd");CString test = str;....char* p = (char*)(const char*)str;p[2] = 'z';strcpy(p, "akfjaksjfakfakfakj");//这下完蛋了你知道此时,test中的值是多少吗?答案是"abzd"。

它也跟着改变了,这不是你所期望发生的。

但为什么会这样呢?你稍微想想就会明白,前面说过,因为CString是指向引用块的,str与test指向同一块地方,当你p[2]='z'后,当然test也会随着改变。

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

假如我想直接通过指针去修改数据的话,那怎样办呢?就是用GetBuffer(...).看下述代码:CString str("abcd");CString test = str;....char* p = str.GetBuffer(20);p[2] = 'z'; // 执行到此,现在test中值却仍是"abcd"strcpy(p, "akfjaksjfakfakfakj"); // 执行到此,现在test 中值还是"abcd"为什么会这样?其实GetBuffer(20)调用时,它实际上另外建立了一块新内块存,并分配20字节长度的buffer,而原来的内存块引用计数也相应减1. 所以执行代码后str与test是指向了两块不同的地方,所以相安无事。

(4) 不过这里还有一点注意事项:就是str.GetBuffer(20)后,str的分配长度为20,即指针p它所指向的buffer只有20字节长,给它赋值时,切不可超过,否则灾难离你不远了;如果指定长度小于原来串长度,如GetBuffer(1),实际上它会分配4个字节长度(即原来串长度);另外,当调用GetBuffer(...)后并改变其内容,一定要记得调用ReleaseBuffer(),这个函数会根据串内容来更新引用内存块的头部信息。

(5) 最后还有一注意事项,看下述代码:char* p = NULL;const char* q = NULL;{CString str = "abcd";q = (LPCTSTR)str;p = str.GetBuffer(20);AfxMessageBox(q);// 合法的strcpy(p, "this is test");//合法的,}AfxMessageBox(q);// 非法的,可能完蛋strcpy(p, "this is test");//非法的,可能完蛋这里要说的就是,当返回这些指针后,如果CString对象生命结束,这些指针也相应无效。

3.拷贝 & 赋值 & "引用内存块" 什么时候释放?下面演示一段代码执行过程void Test(){CString str("abcd");//str指向一引用内存块(引用内存块的引用计数为1,长度为4,分配长度为4)CString a;//a指向一初始数据状态,a = str;//a与str指向同一引用内存块(引用内存块的引用计数为2,长度为4,分配长度为4)CString b(a);//a、b与str指向同一引用内存块(引用内存块的引用计数为3,长度为4,分配长度为4){LPCTSTR temp = (LPCTSTR)a;//temp指向引用内存块的串首地址。

(引用内存块的引用计数为3,长度为4,分配长度为4)CString d = a;//a、b、d与str指向同一引用内存块(引用内存块的引用计数为4, 长度为4,分配长度为4)b = "testa";//这条语句实际是调用CString::operator=(CString&)函数。

b指向一新分配的引用内存块。

(新分配的引用内存块的引用计数为1, 长度为5,分配长度为5)//同时原引用内存块引用计数减1. a、d与str仍指向原引用内存块(引用内存块的引用计数为3,长度为4,分配长度为4)}//由于d生命结束,调用析构函数,导至引用计数减1(引用内存块的引用计数为2,长度为4,分配长度为4)LPTSTR temp = a.GetBuffer(10);//此语句也会导致重新分配新内存块。

temp指向新分配引用内存块的串首地址(新分配的引用内存块的引用计数为1,长度为0,分配长度为10)//同时原引用内存块引用计数减1. 只有str仍指向原引用内存块(引用内存块的引用计数为1, 长度为4, 分配长度为4)strcpy(temp, "temp");//a指向的引用内存块的引用计数为1,长度为0,分配长度为10a.ReleaseBuffer();//注意:a指向的引用内存块的引用计数为1,长度为4,分配长度为10}//执行到此,所有的局部变量生命周期都已结束。

对象str a b 各自调用自己的析构构//函数,所指向的引用内存块也相应减1//注意,str a b 所分别指向的引用内存块的计数均为0,这导致所分配的内存块释放通过观察上面执行过程,我们会发现CString虽然可以多个对象指向同一引用内块存,但是它们在进行各种拷贝、赋值及改变串内容时,它的处理是很智能并且非常安全的,完全做到了互不干涉、互不影响。

相关文档
最新文档