#C++ String# C++ string
“ 文章所涉及内容更多来自网络,在此声明,并感谢知识的贡献者!”
初始
—
String的初始方式
1 string s1;
初始值为空串
2 string s2(s1);
使用s1构造s2
3 string s2=s1;
使用s1构造s2
4 string s3(“value”);
使用字面值“value”构造
5 string s3=“value”;
使用字面值“value”构造
6 string s4(n,’c’)
把s4初始化为由连续n个字符c组成的字符串
7 string s5 = string("value");
调用string的构造函数生成一个临时的string类,再用临时的string类初始化s5。
8 string s6(string("value"));
调用string的构造函数生成一个临时的string类,再用临时的string类初始化s5。
string的拷贝构造
形式:string s(cp,n)
解释:将cp所指的数组的前n个字符拷贝给string对象s,n为可选参数。
const char *cp = "hello world";//最后有一个空字符
char cp2[] = "hello world";//最后有一个空字符
char cp3[] = { 'h', 'e' };//最后没有空字符
(1) string s1(cp);//s1为”hello world”,长度为11
(2) string s2(cp2);//s2为”hello world”,长度为11
(3) string s3(cp3);//因为cp3不以空字符结尾,所以这是未定义行为
(4) string s4(cp,5);//s4为”hello”,长度为5。将cp改为cp2一样
(5) string s5(cp,13);//s5为”hello world ”,长度为13,后面有两个空字符。将cp改为cp2一样
(6) string s6(cp3,2);//s6为”he”,长度为2
形式:
string s(s1,pos)
string s(s1,pos,len)
解释:
第一个将s1从下标pos开始拷贝到结尾。当pos>s1.size()时,为未定义行为;当pos=s1.size(),拷贝一个空字符
第二个将s1从下标pos开始拷贝,拷贝len个字符。当pos>s1.size()时,为未定义行为;当pos=s2.size(),拷贝一个空字符
string s1("value");
(1) string s2(s1, 1);//s2为” alue”,长度为4
(2) string s3(s1, 5);//s3为””,长度为0
(3) string s8(s1, 6);// 错误,未定义的行为,抛出异常
(4) string s4(s1, 1,3);// s4为” alu”,长度为3
(5) string s5(s1, 1,8);// 正确,s5为” alue”,长度为4
(6) string s6(s1, 5,8);// s6为””,长度为0
(7) string s7(s1, 6,1);// 错误,未定义的行为,抛出异常
赋值
—
String的赋值
初始化是生成对象的时候(也就是刚分配内存空间时)就给它值;赋值就是过了初始化后,给对象值。
string st1, st2(2,'b');
st1 = st2; //st1此时已近占据了一块内存
输入
—
用cin获取键盘输入的值
使用cin获取输入的字符串或使用cout输出字符串时,string对象会自动忽略开头的空白(既空格、换行符、制表符等),并从第一个真正的字符开始读入,直到遇到下一处空白
用getline读取一整行
getline的作用是读取一整行,直到遇到换行符才停止读取,期间能读取像空格、Tab等的空白符。实例如下:
string s1;
getline(cin, s1);
cout << s1 << endl;
比较
—
比较string的大小
string str = "Hello";
string phrase = "Hello ";
尽管两者的前面对应的字符都一样,但是phrase长度长(多一个空格),所以phrase>str。
string str2 = "Hello";
string phrase2 = "Hi ";
这种情况比较的是第一个相异字符,根据字符值比较大小,因为i的字符值>e的字符值,所以phrase2> str2。
基于compare函数string比较
compare,它也可以比较字符串,并且有6种不同的参数形式,比较字符串时更加灵活。compare的参数形式如下:
参数形式s.compare() 说明
s2 比较s和s2
pos1, n1, s2 将s中从pos1开始的n1个字符与s2比较
pos1, n1, s2, pos2, n2 将s中从pos1开始的n1个字符与s2中从pos2开始的n2个字符比较
cp 比较s与cp指向的以空字符结尾的数组
pos1, n1, cp 将s中从pos1开始的n1个字符与cp指向的以空字符结尾的数组比较
pos1, n1, cp,n2 将s中从pos1开始的n1个字符与cp指向的以空字符结尾的数组前n个字符比较
拼接
—
string对象间的拼接
string str = "Hello,";
string phrase = "world ";
string s = str + phrase;
string对象与字符(或字符串)字面值的拼接
string str = "Hello";
string phrase = "world";
string s = str + “ , ”+ phrase+ '\n';
string str = "Hello";
(1)string s2 = str + "," + "world";
(2)string s3 = "Hello" + "," + str;
分析:(1)正确;(2)错误
(2)错误的原因是:当string对象和字符或字符串字面值相加时,必须确保+号的两侧的运算对象至少有一个string。
string对象的尾部添加 append
append是在string对象的末尾进行插入操作。这一点使用+运算符也能做到。
string s("i love China!");
s.append("forever");//执行完后,s=” i love China! forever”
string对象的子字符修改
遍历
—
根据下标获取string单个字符的值
string s = "Hello world!";
cout << s[0] << endl;
cout << s[s.size()-1] << endl;
基于迭代器逐个读取string中的字符
string s = "Hello world!";
for (auto i = s.begin(); i != s.end(); i++){
cout << *i << ",";
}
cout << endl;
基于范围的for逐个读取string中的字符
string str("some string");
for (auto c : str)
cout << c << ",";
cout << endl;
字符串获取
—
string获取子字符串
格式:s.substr(pos,n)
解释:返回一个string对象,返回的对象包含s从pos下标开始的n个字符。pos和n均为可选参数。pos默认为下标0;n默认为s.size()-pos。
插入
—
String插入字符
基于迭代器的插入
1 iterator insert( iterator pos, CharT ch )
2 void insert( iterator pos, size_type count, CharT ch )
3 void insert( iterator pos, InputIt first, InputIt last )
4插入初始化列表
string s1("value");
s1.insert(s1.begin(), 's');//执行后,s1为"svalue"
s1.insert(s1.begin(), 1, 's');//执行后,s1为"ssvalue"
s1.insert(s1.begin(), s1.begin(), ++s1.begin());//执行后,s1为"sssvalue"
s1.insert(s1.end(), {'1','2'});//执行后,s1为"sssvalue12"
基于下标的插入
1 basic_string& insert( size_type index, size_type count, CharT ch )
解释:在下标index前插入count个字符ch。
2 basic_string& insert( size_type index, const CharT* s );
basic_string& insert( size_type index, const basic_string& str );
解释:在下标index前插入一个常量字符串或者string对象。
3 basic_string& insert( size_type index, const basic_string& str,
size_type index_str, size_type count );
解释:在下标index前插入str中的从str[index_str]开始的count个字符
4 basic_string& insert( size_type index, const CharT* s, size_type count );
解释:在index前插入常量字符串的count个字符
删除
—
String的删除子字符串
1basic_string & erase(size_type pos=0, size_type n=npos)
解释:如果string对象s调用,它删除s从pos下标开始的n个字符,并返回删除后的s。当pos > s.size()时,报错
2iterator erase(const_iterator position)
解释:如果string对象s调用,它删除s迭代器position位置的字符,并返回下一个字符的迭代器。
3iterator erase(const_iterator first, const_iterator last)
解释:如果string对象s调用,它删除s迭代器[first,last)区间的字符,并返回last字符的迭代器。
string s1("value");
string s2("value");
string s3("value");
string s4("value");
s1.erase();//执行后,s1为空
s2.erase(0,2); //执行后,s2为”lue”
s3.erase(s3.begin());//执行后,s3为”alue”
s4.erase(s4.begin(),++s4.begin());//执行后,s4为”alue”
替换
—
replace可看作是erase和insert的结合体,它删除指定的字符,删除后再插入指定的字符。
和insert一样,可以通过下标或者是迭代器指定位置。
1:下标指定删除的位置
string s("i very love China!");
const char* cp1 = "truly";
const char* cp2 = "truly!!!";
string str1 = "really";
string str2 = "really!!!";
//1.将s从下标2开始删除4个字符,删除后在下标2处插入cp1
s.replace(2,4,cp1);//s=” i truly love China!”
//2.将s从下标2开始删除5个字符,删除后在下标2插入cp2的前5个字符
s.replace(2, 5, cp2,5); //s=” i truly love China!”
//3.将s从下标2开始删除5个字符,删除后在下标2插入str1
s.replace(2, 5, str1);//s=”i really love China!”
//4.将s从下标2开始删除6个字符,删除后在下标2插入str2从下标0开始的6个字符
s.replace(2, 6, str2,0,6);//s=”i really love China!”
//5.将s从下标2开始删除6个字符,删除后在下标2插入4个’*’字符
s.replace(2, 6, 4, '*');//s=”i **** love China!”
2:迭代器指定删除的位置
string s1("bad phrase");
const char* cp3 = "sample";
const char* cp4 = "sample!!!";
string str3 = "useful";
string str4 = "useful!!!";
//1.删除[s1.begin(),s1. begin()+3)区间字符,删除后插入cp3
s1.replace(s1.begin(),s1.begin()+3,cp3);//s1="sample phrase"
//2.删除[s1.begin(),s1. begin()+6)区间字符,删除后插入cp4的前6个字符
s1.replace(s1.begin(),s1.begin()+6,cp4,6);//s1="sample phrase"
//3.删除[s1.begin(),s1. begin()+6)区间字符,删除后插入str3
s1.replace(s1.begin(),s1.begin()+6, str3);//s1="useful phrase"
//4.删除[s1.begin(),s1. begin()+6)区间字符,删除后插入str4[str4.begin(),str4. begin()+6)区间字符
s1.replace(s1.begin(),s1.begin()+6, str4.begin(),str4.begin() + 6);//s1="useful phrase"
//5. 删除[s1.begin(),s1. begin()+6)区间字符,删除后插入4个’*’字符
s1.replace(s1.begin(),s1.begin()+6, 4, '*');//s1="**** phrase"
//6. 删除[s1.begin(),s1. begin()+4)区间字符,删除后插入初始化列表
s1.replace(s1.begin(), s1.begin() + 4, {'3','4','5'});//s1="345 phrase"
string对象的重置
assign方法可以理解为先将原字符串清空,然后赋予新的值作替换。
格式如下,可以发现,就输入参数而言,和“总结insert和replace”这一节中的表的args参数是一样的,这里不在多做说明,直接给出7个例子,在例子中说明。
string& assign (const string& str);
string& assign (const string& str, size_t subpos, size_t sublen);
string& assign (const char* s);
string& assign (const char* s, size_t n);
string& assign (size_t n, char c);
template string& assign (InputIterator first, InputIterator last);
string& assign (initializer_list il);
查找
—
string对象的搜索
string提供6个不同的搜索函数,每个函数都有4个重载版本,所有函数的返回值都为string::size_type值,表示匹配发生位置的下标。
函数形式:
string搜索函数 描述
s.find(args) 在s中查找第一次出现args的下标
s.rfind(args) 在s中查找最后一次出现args的下标
s.find_first_of(args) 在s中查找第一个在args中出现的字符,返回其下标
s.find_first_not_of(args) 在s中查找第一个不在args中出现的字符,返回其下标
s.find_last_of(args) 在s中查找最后一个在args中出现的字符,返回其下标
s.find_last_not_of(args) 在s中查找最后一个不在args中出现的字符,返回其下标
其中args参数格式如下:
args参数格式 描述
c,pos 搜索单个字符。从s中位置pos开始查找字符c。pos可省略,默认值为0
s2,pos 搜索字符串。从s中位置pos开始查找字符串string对象s2。pos可省略,默认值为0
cp,pos 搜索字符串。从s中位置pos开始查找指针cp指向的以空字符结尾的C风格字符串。pos可省略,默认值为0
cp,pos,n 从s中位置pos开始查找指针cp指向的数组的前n个字符。
格式化
—
String格式化
#include <boost/format.hpp>
boost::format f = boost::format("%.2f %s %d");
f % 1.234 %"123" % 12;
std::string s = f.str();
参考资料
—
C++ string使用介绍
https://blog.csdn.net/weixin_43744293/article/details/118299233
利用boost的format C++ string格式化输出
https://www.51sjk.com/b94b128189/