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

相关文章
|
1月前
|
编解码 Java 开发者
Java String类的关键方法总结
以上总结了Java `String` 类最常见和重要功能性方法。每种操作都对应着日常编程任务,并且理解每种操作如何影响及处理 `Strings` 对于任何使用 Java 的开发者来说都至关重要。
273 5
|
5月前
|
对象存储 C++ 容器
c++的string一键介绍
这篇文章旨在帮助读者回忆如何使用string,并提醒注意事项。它不是一篇详细的功能介绍,而是一篇润色文章。先展示重载函数,如果该函数一笔不可带过,就先展示英文原档(附带翻译),最后展示代码实现与举例可以直接去看英文文档,也可以看本篇文章,但是更建议去看英文原档。那么废话少说直接开始进行挨个介绍。
128 3
|
5月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
162 0
|
5月前
|
存储 编译器 C语言
关于string的‘\0‘与string,vector构造特点,反迭代器与迭代器类等的讨论
你真的了解string的'\0'么?你知道创建一个string a("abcddddddddddddddddddddddddd", 16);这样的string对象要创建多少个对象么?你知道string与vector进行扩容时进行了怎么的操作么?你知道怎么求Vector 最大 最小值 索引 位置么?
148 0
|
5月前
|
存储 编译器 程序员
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。
254 0
|
7月前
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
294 12
|
8月前
|
编译器 C++
类和对象(中 )C++
本文详细讲解了C++中的默认成员函数,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载和取地址运算符重载等内容。重点分析了各函数的特点、使用场景及相互关系,如构造函数的主要任务是初始化对象,而非创建空间;析构函数用于清理资源;拷贝构造与赋值运算符的区别在于前者用于创建新对象,后者用于已存在的对象赋值。同时,文章还探讨了运算符重载的规则及其应用场景,并通过实例加深理解。最后强调,若类中存在资源管理,需显式定义拷贝构造和赋值运算符以避免浅拷贝问题。
|
8月前
|
编译器 C++
类和对象(下)C++
本内容主要讲解C++中的初始化列表、类型转换、静态成员、友元、内部类、匿名对象及对象拷贝时的编译器优化。初始化列表用于成员变量定义初始化,尤其对引用、const及无默认构造函数的类类型变量至关重要。类型转换中,`explicit`可禁用隐式转换。静态成员属类而非对象,受访问限定符约束。内部类是独立类,可增强封装性。匿名对象生命周期短,常用于临时场景。编译器会优化对象拷贝以提高效率。最后,鼓励大家通过重复练习提升技能!
|
8月前
|
缓存 安全 Java
《从头开始学java,一天一个知识点》之:字符串处理:String类的核心API
🌱 **《字符串处理:String类的核心API》一分钟速通!** 本文快速介绍Java中String类的3个高频API:`substring`、`indexOf`和`split`,并通过代码示例展示其用法。重点提示:`substring`的结束索引不包含该位置,`split`支持正则表达式。进一步探讨了String不可变性的高效设计原理及企业级编码规范,如避免使用`new String()`、拼接时使用`StringBuilder`等。最后通过互动解密游戏帮助读者巩固知识。 (上一篇:《多维数组与常见操作》 | 下一篇预告:《输入与输出:Scanner与System类》)
240 11
|
8月前
|
Java
课时14:Java数据类型划分(初见String类)
课时14介绍Java数据类型,重点初见String类。通过三个范例讲解:观察String型变量、&quot;+&quot;操作符的使用问题及转义字符的应用。String不是基本数据类型而是引用类型,但使用方式类似基本类型。课程涵盖字符串连接、数学运算与字符串混合使用时的注意事项以及常用转义字符的用法。
259 9