C++ string使用方法详细介绍

mac2026-01-17  5

更多关于STL的文章:STL专栏

文章目录

介绍string成员函数成员函数用法示例1. 构造2. 字符串输入输出3.获取字符串的长度4.获取字符串元素5.字符串内容的修改6.字符串内容的替换7.字符串的比较8.字符串的查找9.string支持迭代器 资料来源 为了防止学习的过程中出现学后忘的情况,我将接触到的知识进行整理,作该笔记,由于本人水平有限,如果出现错误,还望赐正。

介绍

STL(Standard Template Library 标准模板库) 中只有一个字符串类,即 basic_string类 。basic_string 实现管理以 \0 结尾的字符数组,字符类型由模板参数决定。通常,basic_string 被处理为不透明的对象,靠获得只读指针来访问缓冲区,写操作是由 basic_string 的成员函数实现的。

用字符数组存放字符串容易发生数组越界的错误,而且往往难以察觉。因此,C++ 标准模板库设计了 string 数据类型,专门用于字符串处理。string 作为类出现,其集成的操作函数足以完成多数情况下的需要。使用时不必担心内存是否充足、字符串长度等问题。

string 类型的变量就是用来存放字符串的,也叫“string对象”。string 并不是 C++ 的基本数据类型,它是 C++ 标准模板库中的一个“类”。

string成员函数

string 类提供的各种操作函数大致分为八类:构造器和析构器、大小和容量、元素存取、字符串比较、字符串修改、字符串接合、I/O 操作以及搜索和查找 。

函数名称功能构造函数产生或复制字符串析构函数销毁字符串=,assign()赋以新值swap()交换两个字符串的内容+=,append(),push_back()添加字符insert()插入字符back()返回字符串最后一个字符的引用front()返回字符串第一个字符的引用erase(),pop_back()删除字符clear()清空字符串resize()改变字符串的长度shrink_to_fit()请求字符串减小其容量以适合其大小replace()替换字符串+拼接字符串==,! =,<,<=,>,>=,compare()比较字符串内容size(),length()返回字符串长度max_size()返回字符的最大可能个数empty()判断字符串是否为空capacity()返回重新分配之前的字符容量reserve()保留内存以存储一定数量的字符[],at()存/取单一字符>>,getline()从 stream中读取某值<<将值写入 streamcopy()将内容复制为一个 C - stringc_str()将内容以 C - string 形式返回data()将内容以字符数组形式返回substr()返回子字符串find()搜寻某子字符串或字符begin( ),end(),cbegin(),cend()提供正向迭代器支持rbegin(),rend(),crbegin(),crend()提供逆向迭代器支持get_allocator()返回配置器 成员类型定义value_typecharsize_typesize_titeratorchar的随机访问迭代器const_iteratorconst char的随机访问迭代器pointerchar*const_pointerconst char*referencechar&const_referenceconst char&

成员函数用法示例

1. 构造

构造函数有四个参数,其中三个具有默认值。要初始化一个 string 类,可以使用 C 风格字符串或 string 类型对象,也可以使用 C 风格字符串的部分或 string 类型对象的部分或序列。

注意,不能使用字符或者整数去初始化字符串。//如string str (‘abc’), string str(123) 都是错误的

常见的 string 类构造函数有以下几种形式:

typedef basic_string string; string var; //生成空字符串 string var(const basic_string& str); //生成字符串str的复制 string var(const basic_string& str, size_type pos); //将字符串str中始于pos的部分作为构造函数的初始值 string var(const basic_string& str, size_type pos, size_type n); //将字符串str位于区间[pos,pos+n-1]的子字符串作为var的初始值 string var(const char* s); //以C_string类型s作为字符串var的初始值 string var(const char* s, size_type n); //以C_string类型s的前n个字符串作为字符串var的初始值 string var(size_type n, char c);//生成一个字符串,包含n个c字符 string var(InputIterator beg, InputIterator end); //以闭区间[beg, end]内的字符作为字符串var的初始值

析构函数形式如下:

~basic_string() //销毁所有内存,释放内存

【例】

#include<iostream> #include<string> using namespace std; int main() { string str ("12345678"); char ch[ ] = "abcdefgh"; string str_1(str); //将str全部复制给str_1 string str_2(str,3);//从字符串str的第3个元素开始,复制后面的所有元素,并赋值给str_2 string str_3(str, 2, 5); //从字符串str的第2个元素开始,复制5个元素,并赋值给str_3 string str_4(ch);//复制C_string类型字符串,并赋值给str_4 string str_5(ch, 5); //将C_string类型字符串ch的前5个元素赋值给str_5 string str_6(5,'X'); //将5个'X'组成的字符串"XXXXX"赋值给str_6 string str_7(str.begin(), str.end()); //复制字符串str的所有元素,并赋值给 str_7 cout << str << endl; cout << ch << endl; cout << str_1 << endl; cout << str_2 << endl; cout << str_3 << endl; cout << str_4 << endl; cout << str_5 << endl; cout << str_6 << endl; cout << str_7 << endl; return 0; }

以下为程序运行结果:

12345678 abcdefgh 12345678 45678 34567 abcdefgh abcde XXXXX 12345678

2. 字符串输入输出

“<<” 和 “>>” 提供了 C++ 语言的字符串输入和字符串输出功能。"<<" 可以将字符读入一个流中(例如 ostream);">>" 可以实现将以空格或回车为 “结束符” 的字符序列读入到对应的字符串中,并且开头和结尾的空白字符不包括进字符串中。

还有一个常用的 getline() 函数,该函数的原型包括两种形式:

template <class CharType, class Traits, class Allocator > basic_istream<CharType, Traits>& getline (basic_istream<CharType, Traits>& _Istr,basic_string <CharType,Traits, Allocator> &_Str); //上述原型包含 2 个参数:第 1 个参数是输入流;第 2 个参数是保存输入内容的字符串 template <class CharType, class Traits, class Allocator> basic_istream<CharType, Traits>& getline (basic_istream <CharType, Traits>&_ Istr, basic_string <CharType, Traits, Allocator>& _Str,CharType_Delim); //上述原型包含 3 个参数:第 1 个参数是输入流,第 2 个参数保存输入的字符串,第 3 个参数指定分界符

该函数可将整行的所有字符读到字符串中。在读取字符时,遇到文件结束符、分界符、回车符时,将终止读入操作,且文件结束符、分界符、回车符在字符串中不会保存;当已读入的字符数目超过字符串所能容纳的最大字符数时,将会终止读入操作。

【例】

#include<iostream> #include<string> using namespace std; int main() { //三块代码分开执行 string str_1; cin>>str_1; cout<<"第一个:"<< str_1<<endl; /*string str_2; getline(cin,str_2); cout<<"第二个:"<<str_2<<endl;*/ /*string str_3; getline(cin,str_3,'a'); cout<<"第三个:"<<str_3<<endl;*/ return 0; }

下面为程序运行结果(三种情况均输入:qweasd zxc)

第一个:qweasd //>>遇到空格结束 第二个:qweasd zxc //getline读取字符,直到遇见文件结束符、分界符、回车符停止 第三个:qwe //getline遇到分界符a 读取结束

3.获取字符串的长度

string 类型对象包括三种求解字符串长度的函数:size() length()maxsize() capacity()

size() 和 length():这两个函数会返回 string 类型对象中的字符个数,且它们的执行效果相同。max_size():max_size() 函数返回 string 类型对象最多包含的字符数。一旦程序使用长度超过 max_size() 的 string 操作,编译器会拋出 length_error 异常。capacity():该函数返回在重新分配内存之前,string 类型对象所能包含的最大字符数。跟size()不同,它返回的是分配的容量的大小,并不是string里面字符串的长度。

【例】

#include<iostream> #include<string> using namespace std; int main() { string str("abcdef"); unsigned long size = str.size(); unsigned long length = str.length(); unsigned long max = str.max_size(); unsigned long cap = str.capacity(); cout<<"size:"<<size<<endl; cout<<"length:"<<length<<endl; cout<<"max_size:"<<max<<endl; cout<<"capacity:"<<cap<<endl; return 0; }

下面为程序输出结果:

size:6 length:6 max_size:9223372036854775807 capacity:15 //至于这里为什么输出15,还不清楚

string 类型对象包括一个 reserve() 函数。调用该函数可以为 string 类型对象重新分配内存(预分配,此时不能用下标访问新分配的内存)。重新分配的大小由其参数决定。reserve() 的默认参数为 0。 还包含一个 resize() 函数。其功能与 reserve() 相同,但reserve() 只能将内存扩大,而 resize() 可以任意分配内存(直接分配,如果内存变小,则原字符串被截断,如果内存变大,则用’\0’填充,此时可以用下标访问新分配的内存)。

这两个方法分别对应两个属性:capacity() 和 size()

【例】

#include<iostream> #include<string> using namespace std; int main() { string str("abcdef"); str.reserve(40); cout<<"size:"<<str.size()<<endl; cout<<"capacity:"<<str.capacity()<<endl; str.resize(60); //str.shrink_to_fit(); cout<<str<<endl; cout<<"size:"<<str.size()<<endl; cout<<"capacity:"<<str.capacity()<<endl; str.resize(3);//原字符串被截断 cout<<str<<endl; return 0; }

下面为程序运行结果:

size:6 capacity:40 abcdef size:60 capacity:80 abc

上述程序中str.reserve(40);如果将n=40改为0~14,capacity仍输出15,而将n改为15~29时,capacity将输出30。只有改为31及以上,才会输出值n。 此外从运行结果可以看到resize之后,capacity也会发生改变,resize之后(扩大内存)理论上capacity的值与size相同,上述程序由于预先调用了reserve,影响了结果。但是若添加str.shrink_to_fit();,则capacity将会与size相同。

shrink_to_fit()无返回值,功能如下: 请求字符串减小其容量以适合其大小。 该请求是非绑定的,并且容器实现可以自由地进行优化,否则将使字符串的容量大于其大小。 此函数对字符串长度没有影响,并且不能更改其内容。

4.获取字符串元素

字符串中元素的访问是允许的,一般可使用两种方法访问字符串中的单一字符:下标操作符[]成员函数at()。两者均返回指定的下标位置的字符。第 1 个字符索引(下标)为 0,最后的字符索引为 length()-1

需要注意的是,这两种访问方法是有区别的:

下标操作符 [] 在使用时不检查索引的有效性,如果下标超出字符的长度范围,会示导致未定义行为。对于常量字符串,使用下标操作符时,字符串的最后字符(即 ‘\0’)是有效的。对应 string 类型对象(常量型)最后一个字符的下标是有效的,调用返回字符 ‘\0’。函数 at() 在使用时会检查下标是否有效。如果给定的下标超出字符的长度范围,系统会抛出 out_of_range 异常。 #include<iostream> #include<string> using namespace std; int main() { string str("abcdef"); cout<<str[3]<<endl; cout<<str.at(3)<<endl; cout<<str[10]<<endl;//越界,返回'\0',但Qt Creator13.01执行时未报错 cout<<str.at(10)<<endl;//异常 return 0; }

运行结果:

d d terminate called after throwing an instance of ‘std::out_of_range’ what(): basic_string::at: __n (which is 10) >= this->size() (which is 6)

front() 和 back() front()back() 分别返回字符串首、尾字符的引用,无参数。 #include<iostream> #include<string> using namespace std; int main() { string str("abcdef"); cout<<str.front()<<endl; cout<<str.back()<<endl; str.front() = 'c'; str.back() = 'x'; cout<<str<<endl; return 0; }

运行结果为:

a f cbcdex

另外,为了防止使用下标时,字符串尚未初始化等情况,使用empty() 和 size() 或 length()可以有效防止出错。

empty()无参数,功能如下 : 判断字符串是否为空,是返回真,否则返回假。 substr() 返回子字符串

basic_string substr(size_type pos = 0, size_type n = npos) const; //返回区间[pos,pos+n-1]的子字符串

string str("abcdefg"); cout<<str.substr(2,5)<<endl; //输出cdefg

5.字符串内容的修改

可以通过使用多个函数修改字符串的值。例如 assign()operator=erase()operator+pop_back()swap()insert()等。另外,还可通过 append()push_back()函数添加字符,以及clear()清空字符串。

assign() 使用 assign() 函数可以直接给字符串赋值。该函数既可以将整个字符串赋值给新串,也可以将字符串的子串赋值给新串。其在 basic_string 中的原型为:

basic_string& assign(const char* s); //直接使用C_string字符串赋值 basic_string& assign(const char* s, size_type n);//将C_string字符串s前n个字符赋值给调用串 basic_string& assign (const basic_string& str); //使用string字符串賦值 basic_string& assign(const basic_string& str, size_type pos, size_type n = npos); //将str的子串赋值给调用串,n表示长度,默认值为-1(直到字符串末尾) basic_string& assign(size_type n, char c); //使用 n个重复字符賦值 basic_string& assign(InputIterator first, InputIterator last); //使用迭代器赋值

【例】

#include<iostream> #include<string> using namespace std; int main() { string str1("123456"); char s[6] = "abcde"; string str; str.assign(s);//用C_string类型字符串赋值 cout<<str<<endl; str.assign(s,3);//将C_string类型字符串s的前3个字符赋值给str cout<<str<<endl; str.assign(str1);//用string类型字符串赋值 cout<<str<<endl; str.assign(str1,3);//将str1从第3个字符到最后一个字符赋值给str cout<<str<<endl; str.assign(str1,2,3);//将str1从第2个字符开始,长度为3的字符串赋值给str cout<<str<<endl; str.assign(5,'c');//用5个c字符赋值 cout<<str<<endl; str.assign(str1.begin()+2,str1.end()-2);//使用迭代器赋值 cout<<str<<endl; return 0; }

下面为程序运行结果:

abcde abc 123456 456 345 ccccc 34

operator= operator= 的功能就是赋值。

operator+ 将两个或多个字符串拼接起来

string str1("123456"); string str("789"); str = str1 + str; cout<<str<<endl;//输出123456789 push_back() 在字符串末尾追加一个字符,参数为多个字符时,会被截断

void push_back(char c);

string str("abc"); str.push_back('d') cout<<str<<endl;//输出abcd swap() 交换两个字符串的值

void swap (basic_string& str);

string str1("123456"); string str("789"); str.swap(str1); cout<<str<<endl; //输出123456 cout<<str1<<endl;//输出789 pop_back() 删除字符串最后一个字符

void pop_back();

erase() 删除指定子字符串

basic_string& erase(size_type pos = 0, size_type n = npos); //删除从pos开始,长度为n的子字符串(即区间[pos,pos+n-1]的子字符串)(默认删除全部) iterator erase(const_iterator position);//使用迭代器,删除指定的一个字符 iterator erase(const_iterator first, const_iterator last);//使用迭代器,删除指定区间的子字符串

#include<iostream> #include<string> using namespace std; int main() { string str("123456"); str.erase(3);//从第3个开始删除后续所有字符 cout<<str<<endl; str = "123456"; str.erase(3,2);//从第3个开始删除长度为2的子字符串 cout<<str<<endl; str = "123456"; str.erase(str.begin()+3);//删除第3个字符 cout<<str<<endl; str = "123456"; str.erase(str.begin()+2,str.begin()+4);//删除区间[2,4)的子字符串 //str.erase(str.end()-4,str.end()-2); //删除区间{2,4)的子字符串 cout<<str<<endl; return 0; }

运行结果:

123 1236 12356 1256

clear() 清空字符串,该函数无参数,无返回值。

insert() 向指定位置插入字符串

basic_string& insert(size_type pos, const char* s);//在调用串的第pos个元素前面插入C_string类型字符串 basic_string& insert(size_type pos, size_type n, char c);//在调用串的第pos个元素前面插入n个字符c iterator insert(const_iterator p, char c);//使用迭代器,在正向迭代器指向的位置p前面插入单个字符c iterator insert(const_iterator p, size_type n, char c);//在正向迭代器指向的位置p前面插入n个字符c basic_string& insert(size_type pos, const char* s, size_type n); //在调用串的第pos个元素前面插入C_string类型字符串s的前n个字符 basic_string& insert(size_type pos1, const basic_string& str, size_type pos2, size_type n = npos); //在调用串的第pos1个元素前插入字符串str位于区间[pos2,pos2+n -1]的子字符串(n默认直到末尾) basic_string& insert(size_type pos1, const basic_string& str);//在调用串的第pos1个元素前插入字符串str iterator insert(const_iterator p, InputIterator beg, InputIterator end);

【例】

#include<iostream> #include<string> using namespace std; int main() { string str("123456"); string ss("vwxyz"); char s[6] = "abcde"; str.insert(2,s);//在str第2个元素前面插入C_string类型字符串s cout<<str<<endl; str = "123456"; str.insert(2,3,'a');//在str第2个元素前面插入3个字符a cout<<str<<endl; str = "123456"; str.insert(str.begin()+1,'b');//在str第1个元素前面插入字符b cout<<str<<endl; str = "123456"; str.insert(str.begin(),3,'c');//在str第0个元素前面插入3个字符c cout<<str<<endl; str = "123456"; str.insert(3,s,2);//在str第3个元素前面插入c_string类型字符串s的前2位 cout<<str<<endl; str = "123456"; str.insert(2,ss,2,2);//在str第2个元素前面插入字符串ss从第2个元素开始长度为2的子字符串 cout<<str<<endl; str = "123456"; str.insert(2,ss);//在str第2个元素前面插入字符串ss cout<<str<<endl; str = "123456"; str.insert(str.begin()+1,ss.begin()+3,ss.end());//在str第1个元素前面插入字符串ss从第3个元素到最后一个元素所构成的子字符串 cout<<str<<endl; return 0; }

程序运行结果为:

12abcde3456 12aaa3456 1b23456 ccc123456 123ab456 12xy3456 12vwxyz3456 1yz23456

append() 追加字符串

basic_string& append(const basic_string& str);//在调用串末尾添加字符串str basic_string& append(const basic_string& str, size_type pos, size_type n = npos) ;//在调用串末尾添加字符串从第pos个元素开始长度为n的子字符串(即区间[pos,pos+n-1]的子字符串)(n默认直到末尾) basic_string& append(const char* s, size_type n);//在调用串末尾添加c_string类型字符串s的前n个元素 basic_string& append(const char* s);//在调用串末尾添加c_string类型字符串s basic_string& append(size_type n, char c);//在调用串末尾添加n个字符c basic_string& append(InputIterator first, InputIterator last);

【例】

#include<iostream> #include<string> using namespace std; int main() { string str("123456"); string ss("vwxyz"); char s[6] = "abcde"; str.append(ss);//在str末尾添加字符串ss cout<<str<<endl; str = "123456"; str.append(ss,2,2);//在str末尾添加字符串ss从第2个元素开始长度为2的子字符串 cout<<str<<endl; str = "123456"; str.append(s,3);//在str末尾添加c_string类型字符串s的前3个字符 cout<<str<<endl; str = "123456"; str.append(s);//在str末尾添加c_string类型字符串s cout<<str<<endl; str = "123456"; str.append(3,'a');//在str末尾添加3个字符a cout<<str<<endl; str = "123456"; str.append(ss.begin()+1,ss.end());//在str末尾添加字符串ss在区间[1,4]上的子字符串 cout<<str<<endl; return 0; }

程序运行结果为:

123456vwxyz 123456xy 123456abc 123456abcde 123456aaa 123456wxyz

6.字符串内容的替换

如果在一个字符串中标识出具体位置,便可以通过下标操作修改指定位置字符的值,或者替换某个子串。完成此项操作需要使用 string 类的成员函数 replace()

replace() 函数的原型如下:

basic_string& replace(size_type pos, size_type n, const basic_string& str); //将调用串从第pos个元素开始长度为n的子字符串(即区间[pos,pos+n-1]的子字符串)替换为字符串str basic_string& replace(size_type pos1, size_type n1, const basic_string& str,size_type pos2, size_type n2 = npos);//将调用串从第pos1个元素开始长度为n1的子字符串(即区间[pos1,pos1 + n1 -1]的子字符串)替换为字符串str从第pos2个元素开始长度为n2的子字符串(即区间[pos2,pos2 + n2 -1]的子字符串)(n2默认值指向末尾) basic_string& replace(size_type pos, size_type n1, const char* s,size_type n2); //将调用串位于区间[pos,pos+n1 - 1]的子字符串替换为c_string类型字符串s的前n2个字符 basic_string& replace(size_type pos, size_type n1, const char* s); //将调用串位于区间[pos,pos + n1 -1]的子字符串替换为c_string类型字符串s basic_string& replace(size_type pos, size_type n1, size_type n2, char c); //将调用串位于区间[pos,pos + n1 -1]的子字符串替换为n2个字符c basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str); //将迭代器i1,i2指向的元素之间的字符串(包括i1)替换为字符串str basic_string& replace(const_iterator i1, const_iterator i2,const char* s, size_type n); //将迭代器i1,i2指向的元素之间的字符串(包括i1)替换为c_string类型字符串s的前n个字符 basic_string& replace(const_iterator i1, const_iterator i2, const char* s); //将迭代器i1,i2指向的元素之间的字符串(包括i1)替换为c_string类型的字符串s basic_string& replace(const_iterator i1, const_iterator i2, size_type n, char c); //将迭代器i1,i2指向的元素之间的字符串(包括i1)替换为n个字符c basic_string& replace(const_iterator i1, const_iterator i2,InputIterator k1, InputIterator k2); //将迭代器i1,i2指向的元素之间的字符串(包括i1)替换为迭代器k1,k2指向的元素之间的字符串(包括k1) basic_string& replace(const_iterator i1, const_iterator i2 , char* k1, char* k2); //在测试的时候直接输入k2没有作用,要输入k2+(一个常数)表示k2的前几位,在下面的例子会有注释介绍 basic_string& replace(const_iterator i1, const_iterator i2, iterator k1, iterator k2);//使用迭代器替换

【例】

#include<iostream> #include<string> using namespace std; int main() { string str("123456"); string ss("vwxyz"); char s1[6] = "abcde"; char s2[6] = "qwert"; str.replace(2,3,ss);//将str[2,4]的字符串替换为字符串ss cout<<str<<endl; str = "123456"; str.replace(2,3,ss,1,3);//将str[2,4]的字符串替换为字符串ss[1,3] cout<<str<<endl; str = "123456"; str.replace(1,2,s1,3);//将str[1,2]的字符串替换为c_string类型字符串s1的前3个字符 cout<<str<<endl; str = "123456"; str.replace(1,2,s1);//将str[1,2]的字符串替换为c_string类型字符串s1 cout<<str<<endl; str = "123456"; str.replace(3,2,6,'a');//将str[3,4]的字符串替换为6个'a',即aaaaaa cout<<str<<endl; str = "123456"; str.replace(str.begin()+1,str.begin()+4,ss);//将str[1,4)的字符串替换为字符串ss cout<<str<<endl; str = "123456"; str.replace(str.begin()+1,str.begin()+4,s1,3);//将str[1,4)的字符串替换为c_string类型字符串的前3个字符 cout<<str<<endl; str = "123456"; str.replace(str.begin()+1,str.begin()+4,s1);//将str[1,4)的字符串替换为c_string类型字符串s1 cout<<str<<endl; str = "123456"; str.replace(str.begin(),str.begin()+5,6,'c');//将str[0,5)的字符串替换为6个字符c cout<<str<<endl; str = "123456"; str.replace(str.begin()+1,str.begin()+3,s1,s2+3);//将str[1,3)的字符串替换为c_string类型字符串s1+s2的前3个字符 //值的注意的是,s2+n保留s2的前n个字符。而s1+n,则保留s1从第n个字符开始直到末尾的字符串 //即str.replace(str.begin()+1,str.begin()+3,s1+2,s2+3);//则输出1cdeqwe456 cout<<str<<endl; str = "123456"; str.replace(str.begin(),str.end(),ss.begin(),ss.end());//将str替换为ss cout<<str<<endl; return 0; }

以下为程序运行结果:

12vwxyz6 12wxy6 1abc456 1abcde456 123aaaaaa6 1vwxyz56 1abc56 1abcde56 cccccc6 1abcdeqwe456 vwxyz

7.字符串的比较

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

basic_string 类模板既提供了 >、<、==、>=、<=、!= 等比较运算符,还提供了 compare() 函数,其中 compare() 函数支持多参数处理,支持用索引值和长度定位子串进行比较。该函数返回一个整数来表示比较结果。如果相比较的两个子串相同,compare() 函数返回 0,大于返回正值,小于返回负值。

compare() 比较两字符串大小

类 basic_string 的成员函数 compare() 的原型如下:

int compare(const basic_string& str) const;//直接与str比较 int compare(size_type pos, size_type n, const basic_string& str) const; //调用串在区间[pos,pos+n-1]上的子字符串与字符串str比较 int compare(size_type pos1, size_type n1, const basic_string& str,size_type pos2, size_type n2 = npos) const;//调用串在区间[pos1 , pos1 + n1 -1]上的子字符串与字符串str在区间[pos2,pos2+n2 - 1]上的子字符串比较(n2默认指向末尾) int compare(const char* s) const; //直接与c_string类型的字符串s比较 int compare(size_type pos, size_type n1, const char* s) const; //调用串在区间[pos,pos+n1 - 1]上的子字符串与c_string类型字符串s比较 int compare(size_type pos, size_type n1, const char* s,size_type n2) const; //调用串在区间[pos,pos+n1 - 1]上的子字符串与c_string类型字符串s的前n2个字符比较

【例】

#include<iostream> #include<string> using namespace std; string comp(int result) { if(result==0) return "="; else if (result>0) return ">"; else return "<"; } int main() { string str("123456"); string ss("1234"); char s[6] = "123ab"; int result; result = str.compare(ss);//123456与1234比较 cout<<comp(result)<<endl; result = str.compare(0,5,ss);//12345与1234比较 cout<<comp(result)<<endl; result = str.compare(0,2,ss,2,2);//12与34比较 cout<<comp(result)<<endl; result = str.compare(s);//123456与123ab比较 cout<<comp(result)<<endl; result = str.compare(0,3,s);//123与123ab比较 cout<<comp(result)<<endl; result = str.compare(0,3,s,3);//123与123比较 cout<<comp(result)<<endl; return 0; }

下面为程序运行结果:

> > < < < =

重载操作符<,>,==,<=,>=,!= 与数字的比较相同,不再赘述

值得一提的是字符串比较规则:

字符串比较大小并不是比较二者的长度。字符串比较大小,从左数第一个字符开始进行比较进行比较的是两字符的ASCII码的大小逐一进行比较,如果出现差异直接结束比较,否则继续比较下一个字符,直到某一个字符串结束

8.字符串的查找

在 C 语言和 C++ 语言中,可用于实现字符串查找功能的函数非常多。在 STL 中,字符串的查找功能可以实现多种功能,比如说:

搜索单个字符、搜索子串;实现前向搜索、后向搜索;分别实现搜索第一个和最后一个满足条件的字符(或子串);

若查找 find() 函数和其他函数没有搜索到期望的字符(或子串),则返回 npos;若搜索成功,则返回搜索到的第 1 个字符或子串的位置。其中,npos 是一个无符号整数值,初始值为 -1。当搜索失败时, npos 表示“没有找到(not found)”或“所有剩佘字符”。

值得注意的是,所有查找 find() 函数的返回值均是 size_type 类型,即无符号整数类型。该返回值用于表明字符串中元素的个数或者字符在字符串中的位置。

下面分别介绍和字符查找相关的函数。

find()和rfind()

find() 函数的原型有以下 4 种:

size_type find(const char* s, size_type pos, size_type n) const; //第1个参数是被搜索的字符串,第2个参数是源串中开始搜索的下标,第3个参数是关于第1个参数的字符个数,可能是 s 的所有字符数,也可能是 s 的子串宇符个数 size_type find(const basic_string& str, size_type pos = 0) const; //find()函数的第1个参数是被搜索的字符串,第2个参数是在源串中开始搜索的下标位置,默认从头开始搜索 size_type find(const char* s, size_type pos = 0) const; //同上,搜索c_string类型字符串 size_type find(char c, size_type pos = 0) const; //第1个参数是被搜索的单个字符,第2参数是在源串中开始搜索的下标位置,默认从头开始搜索

rfind() 函数的原型和find()函数的原型类似,参数情况也类似。只不过 rfind() 函数适用于实现逆向查找。

【例】

#include<iostream> #include<string> using namespace std; int main() { string str("Try not to become a man of success " "but rather try to become a man of value"); string search("but"); string::size_type position1 = str.find("best"); string::size_type position2 = str.find('o'); string::size_type position3 = str.find("todoit",0,2); cout<<static_cast<int>(position1)<<endl; cout<<static_cast<int>(position2)<<endl; cout<<static_cast<int>(position3)<<endl; string::size_type position4 = str.rfind(search); string::size_type position5 = str.rfind('o'); string::size_type position6 = str.rfind("todoit",string::npos,2); cout<<static_cast<int>(position4)<<endl; cout<<static_cast<int>(position5)<<endl; cout<<static_cast<int>(position6)<<endl; return 0; } find_first_of()和 find_last_of()

find_first_of() 函数可实现在源串中搜索某字符串的功能,该函数的返回值是被搜索字符串的某 1 个字符第 1 次出现的下标(位置)。若查找失败,则返回 npos。

size_type find_first_of(const basic_string& str, size_type pos = 0) const; //搜索str字符串中的字符第一次在调用串中出现的位置,pos为搜索起点,默认从头开始 size_type find_first_of(const char* s, size_type pos, size_type n) const; //搜索c_string类型字符串s的前n个字符第一次在调用串中出现的位置,pos为搜索起点 size_type find_first_of(const char* s, size_type pos = 0) const; //搜索c_string类型字符串s中的字符第一次在调用串中出现的位置,pos为搜索起点,默认从头开始 size_type find_first_of(char c, size_type pos = 0) const; //搜索字符c第一次在调用串中出现的位置,pos为搜索起点,默认从头开始

find_last_of() 函数同样可实现在源串中搜索某字符串的功能。函数的原型和find_first_of()函数的原型类似,参数情况也类似。与 find_first_of() 函数所不同的是,该函数的返回值是被搜索字符串的最后 1 个字符的下标(位置)。若查找失败,则返回 npos。

find_first_not_of()和 find_last_not_of()

find_first_not_of() 函数可实现在源字符串中搜索与指定字符(串)不相等的第 1 个字符; find_last_not_of() 函数可实现在源字符串中搜索与指定字符(串)不相等的最后 1 个字符。 这两个函数的参数及意义与find_first_of() 和 find_last_of()相同,不再赘述。

【例】

#include<iostream> #include<string> using namespace std; int main() { string str("Try not to become a man of success " "but rather try to become a man of value"); string search("but"); char sh[5] = "some"; string::size_type position1 = str.find_first_of("best"); string::size_type position2 = str.find_first_of(sh,34,1);//从str[34]开始搜索第一个为s的字符 string::size_type position3 = str.find_first_of(sh,0); string::size_type position4 = str.find_first_of('v'); cout<<static_cast<int>(position1)<<endl; cout<<static_cast<int>(position2)<<endl; cout<<static_cast<int>(position3)<<endl; cout<<static_cast<int>(position4)<<endl; string::size_type position5 = str.find_first_not_of(" abcTrynot"); string::size_type position6 = str.find_first_not_of(sh,0,2);//搜索第一个不是s,o,m的字符 string::size_type position7 = str.find_first_not_of(sh,0);//从str的头开始搜索第一个不是s,o,m,e的字符 string::size_type position8 = str.find_first_not_of('e');//搜索第一个不是e的字符 cout<<static_cast<int>(position5)<<endl; cout<<static_cast<int>(position6)<<endl; cout<<static_cast<int>(position7)<<endl; cout<<static_cast<int>(position8)<<endl; string::size_type position9 = str.find_last_of(" abcTrynot"); string::size_type position10 = str.find_last_of(sh,string::npos,2); string::size_type position11 = str.find_last_of(sh,string::npos); string::size_type position12 = str.find_last_of('e'); cout<<static_cast<int>(position9)<<endl; cout<<static_cast<int>(position10)<<endl; cout<<static_cast<int>(position11)<<endl; cout<<static_cast<int>(position12)<<endl; string::size_type position13 = str.find_last_not_of(" abcTrynot"); string::size_type position14 = str.find_last_not_of(sh,string::npos,3); string::size_type position15 = str.find_last_not_of(sh,string::npos); string::size_type position16 = str.find_last_not_of('e'); cout<<static_cast<int>(position13)<<endl; cout<<static_cast<int>(position14)<<endl; cout<<static_cast<int>(position15)<<endl; cout<<static_cast<int>(position16)<<endl; return 0; }

程序运行结果为:

6 -1 5 69 12 0 0 0 70 66 73 73 73 73 72 72

9.string支持迭代器

迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。迭代器修改了常规指针的接口,所谓迭代器是一种概念上的抽象:那些行为上像迭代器的东西都可以叫做迭代器。然而迭代器有很多不同的能力,它可以把抽象容器和通用算法有机的统一起来。

迭代器提供一些基本操作符:*、++、==、!=、=。这些操作和C/C++“操作array元素”时的指针接口一致。不同之处在于,迭代器是个所谓的复杂的指针,具有遍历复杂数据结构的能力。其下层运行机制取决于其所遍历的数据结构。因此,每一种容器型都必须提供自己的迭代器。事实上每一种容器都将其迭代器以嵌套的方式定义于内部。因此各种迭代器的接口相同,型号却不同。这直接导出了泛型程序设计的概念:所有操作行为都使用相同接口,虽然它们的型别不同。

STL 定义了 5 种迭代器,根据所需的迭代器类型对算法进行描述。这 5 种迭代器分别是:输入迭代器 输出迭代器 正向迭代器 双向迭代器 随机访问迭代器。对于这 5 种迭代器不仅可以执行解除引用操作(* 操作符),还可进行比较。这里主要讲述 basic_string(或 string 类)中迭代器的使用。

basic_string 和 string 类均提供了常规的迭代器和反向迭代器。string 是字符的有序群集。

C++ 标准库为 string 提供了相应接口,便于将字符串作为 STL 容器使用。可以使用迭代器遍历 string 内的所有字符;也可以使用其他算法遍历 string 内的所有字符。而且能够访问字符串中的每个字符,并对这些字符进行排序、逆向重排、找出最大值等操作。

string 类的迭代器是随机存取迭代器,即支持随机存取。任何一个 STL 算法都可与其搭配使用。通常 string 的“迭代器型别”由 string 类本身定义,通常可以被简单地定义为一般指针。对迭代器而言,如果发生重新分配,或其所指的值发生某些变化时,迭代器会失效。

string 类中和使用迭代器相关的成员函数是很多的,主要包括 begin()、end()、rbegin ()、rend()、append()、assign()、insert()、erase()、replace() 等。

名称功能begin( )返回指向字符串第一个字符的迭代器。end()返回指向字符串最后一个字符(’\0’)的迭代器。cbegin()返回指向字符串第一个字符的const类型迭代器。cend()返回指向字符串最后一个字符(’\0’)的const类型迭代器。rbegin()返回一个反向迭代器,该迭代器指向字符串的最后一个字符(即它的反向开始)。rend()返回一个反向迭代器,该迭代器指向字符串第一个字符之前的理论元素(该字符被视为反向元素)。crbegin()返回一个const类型反向迭代器,该迭代器指向字符串的最后一个字符(即它的反向开始)。crend()返回一个const类型反向迭代器,该迭代器指向字符串第一个字符之前的理论元素(该字符被视为反向元素)。

begin()与cbegin()的区别是 begin()指向非const的字符串时,可以对其进行修改,而cbegin()只能指向const类型字符串(即开头的c表示const,r表示reverse)。其余同上。

#include<iostream> #include<string> #include<algorithm> #include<iterator> using namespace std; int main() { string str("Standing up to your own." "That would take a real hero."); cout<<str<<endl; string::iterator it;//使用正向迭代器遍历字符串 for(it = str.begin();it!=str.end();it++) cout<<*it; //function();//可以进行其他操作 cout<<endl; string::reverse_iterator rev_it;//使用反向迭代器倒序输出字符串 for(rev_it = str.rbegin();rev_it!=str.rend();rev_it++) cout<<*rev_it; //function();//可以进行其他操作 cout<<endl; std::ostreambuf_iterator<char> out_it(std::cout);//使用输出流迭代器正序输出字符串 std::copy(str.begin(),str.end(),out_it); cout<<endl; std::ostreambuf_iterator<char> rev_out_it(std::cout);//使用输出流迭代器倒序输出字符串 std::copy(str.rbegin(),str.rend(),rev_out_it); cout<<endl; //还有各种函数中使用迭代器,在上文已经涉及 return 0; }

程序运行结果为:

Standing up to your own.That would take a real hero. Standing up to your own.That would take a real hero. .oreh laer a ekat dluow tahT.nwo ruoy ot pu gnidnatS Standing up to your own.That would take a real hero. .oreh laer a ekat dluow tahT.nwo ruoy ot pu gnidnatS

资料来源

The C++ Resources Network(http://www.cplusplus.com)C语言中文网(http://m.biancheng.net)百度百科 (https://baike.baidu.com/item/capacity/6299959)百度百科 (https://baike.baidu.com/item/%E8%BF%AD%E4%BB%A3%E5%99%A8)
最新回复(0)