(4)string类的迭代器
1.begin(),end()
begin():返回一个迭代器,该迭代器指向字符串的开始字符。
end():返回一个迭代器,该迭代器指向字符串的结束字符。
迭代器,也是一个用来遍历对象的一个东西,它有自己的类型 iterator ,针对begin(),和end(),也都有自己的const版本,也就是仅可读迭代器。string的迭代器的使用和指针差不多。
当前可以这么理解,随着我们STL的不断学习,会对迭代器有更加深刻的理解。
int main() { string str("helloworld"); //非const迭代器,可读,可写 for (string::iterator it = str.begin();it!=str.end();it++) { *it = '*'; } for (string::iterator it = str.begin(); it != str.end(); it++) { cout << *it << " "; } cout << endl; //const 迭代器 仅可读 const string str1("helloworld"); for (string::const_iterator it = str1.begin(); it != str1.end(); it++) { cout << *it << " "; } return 0; }
2.rbegin() ,rend()
rbegin():返回反向迭代器以反向开始,返回一个反向迭代器,指向字符串的最后一个字符(即其反向开头),反向迭代器向后迭代:增加迭代器会将它们移向字符串的开头。
rend():返回一个反向迭代器,该迭代器指向字符串的第一个字符之前的理论元素(被视为其反向结尾)。
反向迭代器的类型是,reverse_iterator,同时都提供了,const版本。
int main() { string str("helloworld"); for (string::reverse_iterator it = str.rbegin(); it != str.rend(); it++) { cout << *it << " "; } return 0; }
对于迭代器的类型写起来非常的不方便,我们可以使用auto来自动识别。
3.范围for
范围for是将str对象的字符一个一个取出来,放到 c 中。其底层还是使用的迭代器。
int main() { string str("helloworld"); for (auto c : str) { cout << c << " "; } return 0; }
(5) string类对象的修改操作
1.push_bank( )
在字符串后尾插字符c。
int main() { string str("hello"); cout << str << endl; str.push_back('w'); str.push_back('o'); str.push_back('r'); str.push_back('l'); str.push_back('d'); cout << str<<endl; return 0; }
2.append()
在字符串后追加一个字符串,同时也提供了多个版本:
string& append (const string& str):追加一个字符串 str 。
string& append (const string& str, size_t subpos, size_t sublen):追加字符串str的pos位置后的sublen个字符。
string& append (const char* s):追加一个C字符串,(即以‘/0’结束的字符串)。
string& append (const char* s, size_t n):追加C字符串s的后n个字符。
string& append (size_t n, char c):追加 n 个字符 c
int main() { string str; string str1; cout << str << endl; string str2 = "Writing "; //str1追加str2的第四个位置的后三个字符 str1.append(str2, 4,3); //str追加str2 str.append(str2); cout << str << endl; cout << str1 << endl; //str2z追加一个C字符串 str2.append("work"); cout << str2 << endl; //str2追加一个c字符串的前两个字符 str2.append("hello", 2); cout << str2 << endl; //str2追加10个‘#’ str2.append(10, '#'); cout << str2 << endl; return 0; }
3.operator +=
对于上述的push_bank和append其实在string类中使用并不多,我们一般常用operator+=来追加字符串或者追加字符。
例:
int main() { string str1("hello"); string str2("world"); str1 += str2; cout << str1 << endl; return 0; }
4.insert ()
字符串插入函数,可以支持在某一位,或者迭代器位置插入固定个数的字符,和字符串。
例:
int main() { string str1("hello"); string str2("world"); int pos = 0; //1.在pos位置插入一个 string str2.insert(pos, str1); cout << str2 << endl; string str3("bcde"); int size = 5; //2.在pos位置插入size个字符a str3.insert(pos, size, 'a'); cout << str3 << endl; string str4("bcde"); //3.插入位置还可以是迭代器 str4.insert(str4.begin(), 10, 'A'); cout << str4 << endl; string str5("world"); const char* cstr = "hello "; //3.在pos位置插入一个 C风格字符串。 str4.insert(pos,cstr); cout << str5 << endl; return 0; }
注意:insert,在插入时,特别是在字符串的前部插入是,会有字符的移动消耗。相当于顺序表的头插。
5.erase()
rases字符串的一部分,缩短其长度。
例:
int main() { int pos = 5; int size = 3; string str1("hello C++"); string str2 = str1; cout << "erase前str1:" << str1 << endl; cout << "erase前str2:" << str2 << endl; //删除pos位置包括pos位置的后size个字符,删除位置也可以是一段迭代器区间 str1.erase(pos, size); str2.erase(str2.begin()+5,str2.begin()+5+3); cout << "erase后str1:" << str1 << endl; cout << "erase后str2:" << str2 << endl; return 0; }
注意:
如果给出的删除个数大于字符串后面的字符数,就会将后面字符全部删除。
如果不给出删除位置设定的缺省参数从0开始删除。
如果不给出删除个数,缺省参数设定的删除个数是 size_t npos = -1,约42亿。
删除以后字符串的长度(length)会变,但是容量(capacity)不会变。
6.swap()
swap交换函数,非功能上非常简单,就不多介绍了。但是在 std 里面也有一个swap,我们两个swap来对比一下。
std::swap()底层是一个由借助函数模板实现。不仅仅可以对string类型,对任何可以修改的类型都可以实现交换。
原理类似:
template<class T> void Swap(T& e1,T& e2) { T tmp = e1; e1 = e2; e2 = tmp; }
string::swap()底层是交换string里面的字符串指针来实现的,总体效率要比std::swap()高得多。
(6)字符串相关算法
1.c_str()
返回一个C风格字符串。
2.find()
在字符串中搜索由其参数指定的序列的第一个匹配项。
指定pos时,搜索仅包括位置pos处或之后的字符,忽略任何可能出现的位置pos之前的字符。
例如:
int main() { string str = "this is a string"; //从1位置开始查找字符a,并返回位置。 size_t pos = str.find('a', 1); cout << "a 在" << pos << "位置" << endl; return 0; }
注意:
如果未给出查找位置,就从缺省位置0开始查找。
如果没有找到会返回size_t npos = -1。
3.substr()
返回一个新构造的字符串对象,该对象的值初始化为此对象的子字符串的副本。
子字符串是对象的一部分,从字符位置pos开始,跨越len个字符(或直到字符串结束,以先到者为准)。
例:
int main() { int pos = 0; int length = 4; string str = "this is a string"; //返回一个从pos位置开始,跨越长度为4的子串。 string Substr = str.substr(0, 4); cout << "Substr:" << Substr << endl; return 0; }
注意:
如果没给出起始位置,缺省参数设置为0。
如果没给出跨越长度,缺省参数设置为size_t npos = -1。
(7) 非成员函数重载
1.getline()
从is中提取字符并将其存储到str中,直到找到定界字符delim。没有delim时默认是 ' \n '为定界符 。
例:
int main() { string str; cout << "输入:"; std::getline(cin, str,'a'); cout << "str:" << str << endl; return 0; }