C++ STL string类2

简介: C++ STL string类2

(4)string类的迭代器

1.begin(),end()


07a4184b55e1429db6a4e40cd7b5213e.png

d87db8c496a14c23b3824262abab7394.png


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;
}


e5e248d2e24e400b965d413d13dac885.png


注意:


如果给出的删除个数大于字符串后面的字符数,就会将后面字符全部删除。

如果不给出删除位置设定的缺省参数从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()


0c59a4c6720049ce989f99d7fe6a6d68.png


在字符串中搜索由其参数指定的序列的第一个匹配项。

指定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()


3578a483de954c589cf1b9410df3f8b1.png


返回一个新构造的字符串对象,该对象的值初始化为此对象的子字符串的副本。

子字符串是对象的一部分,从字符位置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;
}


6292c37acc764c85ae5b1f1688e8098b.png


注意:

如果没给出起始位置,缺省参数设置为0。

如果没给出跨越长度,缺省参数设置为size_t npos = -1。


(7) 非成员函数重载

1.getline()


b0da33e607334942b2f77ad91c2bc991.png


从is中提取字符并将其存储到str中,直到找到定界字符delim。没有delim时默认是 ' \n '为定界符 。

例:

int main()
{
  string str;
  cout << "输入:";
  std::getline(cin, str,'a');
  cout << "str:" << str << endl;
  return 0;
}


29d942cdb1404316a4f334704df179ea.png

相关文章
|
19天前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
21 4
|
19天前
|
编译器 C语言 C++
【C++打怪之路Lv4】-- 类和对象(中)
【C++打怪之路Lv4】-- 类和对象(中)
18 4
|
20天前
|
存储 程序员 C++
C++常用基础知识—STL库(2)
C++常用基础知识—STL库(2)
60 5
|
19天前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
17 1
|
20天前
|
存储 自然语言处理 程序员
C++常用基础知识—STL库(1)
C++常用基础知识—STL库(1)
44 1
|
20天前
|
存储 编译器 C语言
【C++打怪之路Lv3】-- 类和对象(上)
【C++打怪之路Lv3】-- 类和对象(上)
15 0
|
22天前
|
算法 数据处理 C++
c++ STL划分算法;partition()、partition_copy()、stable_partition()、partition_point()详解
这些算法是C++ STL中处理和组织数据的强大工具,能够高效地实现复杂的数据处理逻辑。理解它们的差异和应用场景,将有助于编写更加高效和清晰的C++代码。
16 0
|
29天前
|
存储 编译器 C++
【C++类和对象(下)】——我与C++的不解之缘(五)
【C++类和对象(下)】——我与C++的不解之缘(五)
|
29天前
|
编译器 C++
【C++类和对象(中)】—— 我与C++的不解之缘(四)
【C++类和对象(中)】—— 我与C++的不解之缘(四)
|
30天前
|
C++
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
51 1