把标准string类和标准模板库分开来写~同时有附录F中的内容。
头文件string.h和cstring支持对C风格字符串操作,但不支持string类。string类是C++时代产生的,所以要用#include<string>
!!
string类构造函数:
//1
string one("robin");
cout<<one<<endl;
//2
string two(10, '$');
cout<<two<<endl;
//3
string three(one);
cout<<three<<endl;
//4
string four;
cout<<four<<endl;
//5
char alls[] = "abcdefghijklmnopqrstuvwxyz";
string five(alls, 20);
cout<<five<<endl;
//6
string six(alls+5, alls+10);
cout<<six<<endl;
//7
string seven(five, 5, 10);
cout<<seven<<endl;
C11新增的最后两个遇到再说吧~最后一个让string类能够使用列表初始化,也就是下面是合法的:
string piano_man = {'L', 'e', 'e'};
string类输入
string类对象有两种方式输入,一种是重载的>>
另外一种就是getline()函数。
//重载的>>用于string对象输入
string my;
cin>>my;
//输入:abc 输出:abc
//输入:ab cd 输出:ab
从测试情况看,string版本的operator>>
会不断读取直到遇到两种情况停止:
1、空白字符。将其留在输入流中。空白字符包括空格、换行、制表等。
2、分界字符。将其丢弃。分界字符一般为’\n’,也就是你结束输入时的回车。
再测试一下getline()函数。
getline函数要对比C风格字符串来看。
//getline()函数用于C风格字符串输入
char info[100];
cin.getline(info,100);
//getline()函数用于string类型对象输入
string my;
getline(cin, my);
着重注意使用方式!
C风格用法是:cin.getline(info,100);
。根本原因是用于C风格的getline()是istream类的一个方法,所以要用cin对象去调用方法函数。
string类型用法是:getline(cin, my);
。因为用于string类型字符串的getline()是一个独立函数,cin对象只是被当做参数传入其中。
string类型getline()函数遇到三种情况会停止读取:
1、到达文件末尾(废话。。。)。
2、遇到分解符(‘\n’,也好理解,本身就是读取一行,遇到分界回车了肯定要停止)。流中读出并丢弃。
3、string最大的好处就是不用实现规定长度,但是内存容量在实际上还是存在上限的,所以到达最大允许存储时还是会停止,不过一般不会触发。。。
另外一点就是不论是C风格还是string类型的getline(),都会有一个可选参数,就是读到停止:
string my;
getline(cin, my, 'x');//规定读到'x'字符停止。
//如果输入:abcxabc
//则输出为:abc //果然从输出看,在x前停止了。
//也就是说在x之前停止了,不读了,放在输入流中了。
字符串存取:
两种方式:operator[]和at():
string word("tack");
word[1]; //'a'
word.at(2); //'c'
substr()返回从pos开始,往后n个字符(或者直接到头的)的字符串。
//定义:
basic_string substr(size_type __pos = 0, size_type __n = npos) const
//用法:
string message("Maybe the donkey will learn to sing.");
string pet (message.substr(10, 6));//pet = "donkey"
front()访问第一个元素。
back()访问最后一个元素。
字符串搜索:
string类提供了6种搜索函数每种有4个原型:
1、find()系列
2、rfind()系列
3、find _first_of()系列
4、find_last_of()系列
5、find_first_not_of()系列
6、find_last_not_of()系列
挨个说:
find()系列原型:
size_type find (const basic_string& str, size_type pos = 0) const noexcept;
size_type find (const chatT* s, size_type pos = 0) const;
size_type find (const chatT* s, size_type pos, size_type n) const;
size_type find (charT c, size_type pos = 0) const noexcept;
第一个原型搜索整个子字符串第一次出现时的起始位置。从pose开始搜索,若未找到则返回npos。
举例:
string longer("That is a funny hat.");
string shorter("hat");
size_type loc1 = longer.find(shorter); //loc1为1
size_type loc2 = longer.find(shorter, 2); //loc2为16
第一句从默认位置0开始,在”That is a funny hat.”查找”hat”出现的位置,在1位置就有(从0开始)。
第二条从2位置开始,也就是从a开始的,所以要找到hat,只能到最后了,在16位置上。
未找到时一般用npos来输出提醒:
if (loc == string::npos)
cout<<"not found"<<endl;
第二个原型功能一样,只是使用字符数组作为子字符串,而不是string对象。
size_type loc3 = longer.find("is"); //loc3为5;
第三个原型与第二个功能一样,但只使用字符串s的前n个字符。
size_type loc4 = longer.find("funds", 3); //loc4为10;
第四个原型跟第一个一样,只是使用的是字符,不是字符串。
size_type loc5 = longer.find('a'); //loc5为2;
rfind()系列原型:
size_type rfind (const basic_string& __str, size_type __pos = npos) const
_GLIBCXX_NOEXCEPT;
size_type rfind(const _CharT* __s, size_type __pos = npos) const;
size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const;
size_type rfind(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT;
find的倒序功能,搜索字符串最后一次出现的位置。就是从末尾开始查找字符串出现的位置!
string longer("That is a funny hat.");
string shorter("hat");
size_type loc1 = longer.rfind(shorter); //不再是find返回的1,而是16。
size_type loc2 = longer.rfind(shorter, 2); //不再是find返回的16,而是1。
find _first_of()系列原型
size_type find_first_of(const basic_string& __str, size_type __pos = 0) const;
size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const;
size_type find_first_of(const _CharT* __s, size_type __pos = 0) const;
size_type find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
find和rfind方法是搜索的整个子字符串,也就是整个子字符串必须严格对应上才可以。而find _first_of()不以整个字符串为整体,而是搜索子字符串中字符首次出现的位置与find()工作方式类似。
string longer("That is a funny hat.");
string shorter("fluke");
size_type loc1 = longer.find_first_of(shorter); //loc1为10。
size_type loc2 = longer.find_first_of("fat"); //loc2为2。
在longer中,首次出现的fluke中的字符是funny中的f,而首次出现的fat中的字符是That中的a。
find_last_of()系列原型
size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _GLIBCXX_NOEXCEPT
size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const;
size_type find_last_of(const _CharT* __s, size_type __pos = npos) const
size_type find_last_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT
同样是搜索自字符串中字符出现的最后位置,工作方式跟rfind()类似。
下面代码在一个字符串中查找”hat”和”any”中字母最后出现的位置:
string longer("That is a funny hat.");
string shorter("hat");
size_type loc1 = longer.find_last_of(shorter); //loc1为18。
size_type loc2 = longer.find_last_of("any"); //loc2为17。
在longer中,最后出现的hat中的字符是hat中的t,而最后出现的any中的字符是hat中的a。
find_first_not_of()系列原型:
size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const;
size_type find_first_not_of(const _CharT* __s, size_type __pos = 0) const
size_type find_first_not_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT;
与find_first_of()类似,只是搜索第一个不位于子字符串中的字符。
下面在字符串中查找第一个没有出现在”This”和”Thatch”中的字母:
string longer("That is a funny hat.");
string shorter("This");
size_type loc1 = longer.find_first_not_of(shorter); //loc1为2。
size_type loc2 = longer.find_first_not_of("Thatch"); //loc2为4。
在longer中,That中的a是第一个在This中没有出现的字符,而字符串longer中的第一个空格是第一个没有在Thatch在出现的字符。
find_last_not_of()系列原型
size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _GLIBCXX_NOEXCEPT
size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const;
size_type find_last_not_of(const _CharT* __s, size_type __pos = npos) const
size_type find_last_not_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT;
这些方法与对应的find_last_of()工作方式相同,但他们搜索的是最后一个没有在字符串中出现的字符。
在字符串中查找最后一个没有出现在”That.”中的字符。
string longer("That is a funny hat.");
string shorter("That");
size_type loc1 = longer.find_last_not_of(shorter); //loc1为15。
size_type loc2 = longer.find_last_not_of(shorter, 10); //loc2为10。
在longer中,最后的空格是最后一个没有出现在shorter中的字符,而longer字符串中的f是搜索到位置10时,最后一个没有出现在shorter中的字符。
比较方法和函数
6种关系运算符都是可用的,比较大小时是根据ASIC码来的(数字<大写字母<小写字母
),比较点是第一个不同的字符。
除了关系符还有compare()方法。这里不细说了,好啰嗦。。。
字符串修改
拼接有重载的加号运算符,还有append()方法。
assign()方法可以将整个字符串或者字符串部分或者由相同字符组成的字符序列赋值给string对象:
string test;
string stuff("set tubs clones ducks");
test.assign(stuff, 1, 5);//test is "et tu"
test.assign('#', 6);//test is "######"
插入有insert()方法,能将string对象、字符串数组或几个字符插入到string对象中。接受一个指定插入位置的参数,数据被插入到指定位置前面。
//将"former"插入到"The banker."中b的前面:
string st3("The banker.");
st3.insert(4, "former");//插入位置在前面,插入数据在后面
//将字符串中的部分插入到字符串的某个位置:
st3.insert(st3.size()-1, "waltzed!", 2);
//将"waltzed!"中的前两个字符,也就是"wa"插入到st3的倒数第二个位置。
清除:erase()和pop_back()
看下常用的一个原型:
basic_string& erase(size_type pos = 0, size_type n = npos);
可以看出功能就是从pos位置开始,删除n个字符。默认值分别是开头和末尾。
pop_back()删除字符串的最后一个字符(有点弹出一个数据的味道。。)。
替换:replace(),原型很多,就直接举例子说最简单的用法吧,特别具体的感觉一般用到时看下源码:
string teset("Take a right turn at Main Street");
test.raplace(7, 5, "left");//replace right with left.
//从第7个字符开始往后替换5个字符
其他方法:
copy()将string对象或其中的一部分复制到指定的字符串数组中:
//函数原型
size_type copy(charT* s, size_type n, size_type pos = 0) const;
s指向目标数组、n是要复制的字符数、pos指出从string对象的复制开始位置。
在复制了n个字符或达到string对象的最后一个字符时停止。
函数返回复制的字符数。
注意:不追加空字符、不检查长度。
swap()用来交换两个string对象的内容:
void swap(basic_string& str);
返回字符串中字符数。
.size()和.length()成员函数都可以。length是早期版本定义的,size是后来为了兼容STL又添加的。