C++STL之string类

简介: C++STL之string类

一、string 容器基本概念

       C 风格字符串(以空字符结尾的字符数组)太过复杂难于掌握, 不适合大程序的开发, 所以 C++标准库定义了一种 string 类, 定义在头文件。

       String 和 c 风格字串对比:

       Char*是一个指针, String 是一个类

       string 封装了 char, 管理这个字符串, 是一个 char 型的容器。

       String 封装了很多实用的成员方法

       查找 find, 拷贝 copy, 删除 delete 替换 replace, 插入 insert

       不用考虑内存释放和越界:

       string 管理 char*所分配的内存。 每一次 string 的复制, 取值都由 string 类负责维

护, 不用担心复制越界和取值越界等。 算法  

二、string 容器常用操作(结构+ 🌰)

     🌹 1、string的构造 和 赋值

         string 构造函数
string();//创建一个空的字符串 例如: string str;
string(const string& str);//使用一个 string 对象初始化另一个 string 对象
string(const char* s);//使用字符串 s 初始化
string(int n, char c);//使用 n 个字符 c 初始化 v
 string 基本赋值操作
string& operator=(const char* s);//char*类型字符串 赋值给当前的字符串
string& operator=(const string &s);//把字符串 s 赋给当前的字符串
string& operator=(char c);//字符赋值给当前的字符串
string& assign(const char *s);//把字符串 s 赋给当前的字符串
string& assign(const char *s, int n);//把字符串 s 的前 n 个字符赋给当前的字符串
string& assign(const string &s);//把字符串 s 赋给当前字符串
string& assign(int n, char c);//用 n 个字符 c 赋给当前字符串
string& assign(const string &s, int start, int n);//将 s 从 start 开始 n 个字符赋值给字符串

  🌰

void test01()
 {
   //string(const char* s);//使用字符串s初始化
   string str1("hello string");
   cout << str1 << endl;//"hello string"
   //string(int n, char c);//使用n个字符c初始化
   string str2(10, 'H');
   cout << str2 << endl;//"HHHHHHHHHH"
   string str3 = str2;
   cout << str3 << endl;//"HHHHHHHHHH"
   string str4;
   //string& operator=(const string &s);//把字符串s赋给当前的字符串
   str4 = str1;
   cout << str4 << endl;//"hello string"
   //string& operator=(const char* s);//char*类型字符串 赋值给当前的字符串
   string str5;
   str5 = "hello str5";
   cout << str5 << endl;//"hello str5"
   //string& operator=(char c);//字符赋值给当前的字符串
   string str6;
   str6 = 'H';
   cout << str6 << endl;//"H"
   //string& assign(const char *s);//把字符串s赋给当前的字符串
   string str7;
   str7.assign("hello str7");
   cout << str7 << endl;//"hello str7"
   //string& assign(const char *s, int n);//把字符串s的前n个字符赋给当前的字符串
   string str8;
   str8.assign("hello str8", 5);
   cout << str8 << endl;//"hello"
   //string& assign(const string &s);//把字符串s赋给当前字符串
   string str9;
   str9.assign(str8);
   cout << str9 << endl;//"hello"
   //string& assign(int n, char c);//用n个字符c赋给当前字符串
   string str10;
   str10.assign(10, 'W');
   cout << str10 << endl;//"WWWWWWWWWW"
   //string& assign(const string &s, int start, int n);//将s从start开始n个
   string str11;
   str11.assign("hehehahahaxixi", 4, 6);
   cout << str11 << endl;//"hahaha"
   }

   运行效果:


       🍀2、string的字符的存取

char& operator[](int n);//通过[]方式取字符
char& at(int n);//通过 at 方法获取字符

🌰

void test02()
{
  string str1 = "hello string";
  cout << str1[1] << endl;//'e'
  cout << str1.at(1) << endl;//'e'
  str1[1] = 'E';
  cout << str1 << endl;//"hEllo string"
  str1.at(7) = 'T';
  cout << str1 << endl;//"hEllo sTring"
}

  运行效果:

   

       [ ]和at的区别
void test03()
{ //[]和at的区别
  string str1 = "hello string";
     try
     {
     //str1[1000]='G';//越界 []不抛出异常
       str1.at(1000) = 'G';//越界 at会抛出异常
     }
   catch (exception& e)
     {
     cout << "异常:" << e.what() << endl;
     }
   }

 🍁3、string 拼接操作

string& operator+=(const string& str);//重载+=操作符
string& operator+=(const char* str);//重载+=操作符
string& operator+=(const char c);//重载+=操作符
string& append(const char *s);//把字符串 s 连接到当前字符串结尾
string& append(const char *s, int n);//把字符串 s 的前 n 个字符连接到当前字符串结尾
string& append(const string &s);//同 operator+=()
string& append(const string &s, int pos, int n);//把字符串 s 中从 pos 开始
//的 n 个字符连接到当前字符串结尾
string& append(int n, char c);//在当前字符串结尾添加 n 个字符 c

   🌰

void test03()
 {
   string str1 = "hello";
   string str2 = " string";
   //string& operator+=(const string& str);//重载+=操作符
   str1 += str2;
   cout << str1 << endl;//"hello string"
   string str3 = "hello";
   //string& operator+=(const char* str);//重载+=操作符
   str3 += " string";
   cout << str3 << endl;//"hello string"
   string str4 = "hello";
   //string& append(const char *s, int n);//把字符串s的前n个字符连接到当前字符串结尾
   str4.append("hehehaha", 4);
   cout << str4 << endl;//"hellohehe"
   //string& append(const string &s, int pos, int n);//把字符串s中从pos开始的n个字符连接到当前字符串结尾
   string str5 = "hello";
   string str6 = "hehehahaha";
   str5.append(str6, 4, 6);
   cout << str6 << endl;//"hellohahaha"
   }

  运行效果:


       🍂4、字符串的查找替换

int find(const string& str, int pos = 0) const; //查找 str 第一次出现位置,从 pos 开始查找
int find(const char* s, int pos = 0) const; //查找 s 第一次出现位置,从 pos开始查找
int find(const char* s, int pos, int n) const; //从 pos 位置查找 s 的前 n 个字符第一次位置
int find(const char c, int pos = 0) const; //查找字符 c 第一次出现位置
int rfind(const string& str, int pos = npos) const;//查找 str 最后一次位置,从 pos 开始查找
int rfind(const char* s, int pos = npos) const;//查找 s 最后一次出现位置,从pos 开始查找
int rfind(const char* s, int pos, int n) const;//从 pos 查找 s 的前 n 个字符最后一次位置
int rfind(const char c, int pos = 0) const; //查找字符 c 最后一次出现位置
string& replace(int pos, int n, const string& str); //替换从 pos 开始 n 个字符为字符串 str
string& replace(int pos, int n, const char* s); //替换从 pos 开始的 n 个字符为字符串 s

     🌰

void test04()
 {
   //int find(const string& str, int pos = 0) const; //查找str第一次出现位置, 从pos开始查找
   string str1 = "hehe:haha:xixi:haha:heihei";
   //从str1中找haha
   string tmp = "haha";
   cout << str1.find(tmp) << endl;//5
   cout << str1.find(tmp, 10) << endl;//15
   //int find(const char* s, int pos = 0) const; //查找s第一次出现位置,从pos开始查找
   cout << str1.find("haha") << endl;//527
   str1.replace(5, 4, "###");
   cout << str1 << endl;//"hehe:###:xixi:haha:heihei"
   string str2 = "www.sex.117114.sex.person.77.com";
   //需求:将字符串中的所有"sex"用***屏蔽
   int ret = 0;
   while ((ret = str2.find("sex")) < str2.size())
     {
     str2.replace(ret, strlen("sex"), "***");
     }
   cout << str2 << endl;
   }

运行效果:


       🍃5、string 比较操作

/*
compare 函数在>时返回 1, <时返回 -1, ==时返回 0。
比较区分大小写, 比较时参考字典顺序, 排越前面的越小。大写的 A 比小写的 a 小。
*/
int compare(const string &s) const;//与字符串 s 比较
int compare(const char *s) const;//与字符串 s 比较

 🌰

void test05()
 {
   string str1 = "hehe";
   string str2 = "haha"; 
   cout << str1.compare(str2) << endl;//1
   cout << str1.compare("lala") << endl;//‐1
   cout << str1.compare("hehe") << endl;//0
   }

       运行效果:


       🌷6、字符串提取

string substr(int pos = 0, int n = npos) const;//返回由 pos 开始的 n 个字符组成的字符串

🌰

void test06()
 {
   string str1 = "hehehe:ha:xixixi:lalala:heihei";
   //cout<<str1.substr(5,4)<<endl;
     //案例:将:分割的所有字符串提取出来
     int pos = 0;
     while (1)
     {
     int ret = str1.find(":", pos);
     if (ret < 0)
       {
       string tmp = str1.substr(pos, str1.size()-pos);
       cout << tmp << endl;
       break;
       }
       string tmp = str1.substr(pos, ret-pos);
     cout << tmp << endl;
       pos = ret + 1;
     }
   }

       这里特别解释一下为啥当ret<0时作为退出条件,因为当find没找到是他会默认找到最后面,也就是一长串的1。通过二进制转换后发现最后的结果为-1!

        运行效果:


       🌸7、字符串的插入删除

string& insert(int pos, const char* s); //插入字符串
string& insert(int pos, const string& str); //插入字符串
string& insert(int pos, int n, char c);//在指定位置插入 n 个字符 c
string& erase(int pos, int n = npos);//删除从 Pos 开始的 n 个字符

🌰

void test07()
 {
   string str1 = "hello world"; 
   str1.insert(5, "hehe");
   cout << str1 << endl;//"hellohehe world
   str1.erase(5, 4);//删除字符串中hehe
   cout << str1 << endl;//"hello world"
   //清空字符串 str1.size()得到字符串的总大小
   str1.erase(0, str1.size());
   cout << str1.size() << endl;//0
   }

运行效果:


       💮8、string 和C风格的字符串转换

       在 c++中存在一个从 const char 到 string 的隐式类型转换, 却不存在从一个 string

对象到 Cstring 的自动类型转换。 对于 string 类型的字符串, 可以通过 cstr()函数返回 string 对象对应的 C_string. 通常, 程序员在整个程序中应坚持使用 string 类对象, 直到必须将内容转化为 char 时才将其转换为 C_string。

       提示: 为了修改 string 字符串的内容, 下标操作符[]和 at 都会返回字符的引用。

但当字符串的内存被重新分配之后, 可能发生错误。

//string 转 char*
string str = "itcast";
const char* cstr = str.c_str();
//char* 转 string
char* s = "itcast";
string str(s);

  🌰

void test08()
 {
   char str2[] = "hello str";
  //将char * 转成 string (直接完成)
   string str1(str2);
   cout << str1 << endl;//hello str
   string str3 = "hello str3";
   //不能直接将string 转换成 char * 必须借助string中的c_str方法完成
   //char *str4 = str3;//err
   char* str4 = const_cast<char*> (str3.c_str());
   cout << str4 << endl;//"hello str3"
   }

    运行效果:


               感谢你耐心的看到这里ღ( ´・ᴗ・` )比心,如有哪里有错误请踢一脚作者o(╥﹏╥)o!  

相关文章
|
7月前
|
缓存 算法 程序员
C++STL底层原理:探秘标准模板库的内部机制
🌟蒋星熠Jaxonic带你深入STL底层:从容器内存管理到红黑树、哈希表,剖析迭代器、算法与分配器核心机制,揭秘C++标准库的高效设计哲学与性能优化实践。
C++STL底层原理:探秘标准模板库的内部机制
|
编译器 C++ 容器
【c++丨STL】基于红黑树模拟实现set和map(附源码)
本文基于红黑树的实现,模拟了STL中的`set`和`map`容器。通过封装同一棵红黑树并进行适配修改,实现了两种容器的功能。主要步骤包括:1) 修改红黑树节点结构以支持不同数据类型;2) 使用仿函数适配键值比较逻辑;3) 实现双向迭代器支持遍历操作;4) 封装`insert`、`find`等接口,并为`map`实现`operator[]`。最终,通过测试代码验证了功能的正确性。此实现减少了代码冗余,展示了模板与仿函数的强大灵活性。
373 2
|
7月前
|
编解码 Java 开发者
Java String类的关键方法总结
以上总结了Java `String` 类最常见和重要功能性方法。每种操作都对应着日常编程任务,并且理解每种操作如何影响及处理 `Strings` 对于任何使用 Java 的开发者来说都至关重要。
454 5
|
存储 算法 C++
【c++丨STL】map/multimap的使用
本文详细介绍了STL关联式容器中的`map`和`multimap`的使用方法。`map`基于红黑树实现,内部元素按键自动升序排列,存储键值对,支持通过键访问或修改值;而`multimap`允许存在重复键。文章从构造函数、迭代器、容量接口、元素访问接口、增删操作到其他操作接口全面解析了`map`的功能,并通过实例演示了如何用`map`统计字符串数组中各元素的出现次数。最后对比了`map`与`set`的区别,强调了`map`在处理键值关系时的优势。
754 73
|
11月前
|
对象存储 C++ 容器
c++的string一键介绍
这篇文章旨在帮助读者回忆如何使用string,并提醒注意事项。它不是一篇详细的功能介绍,而是一篇润色文章。先展示重载函数,如果该函数一笔不可带过,就先展示英文原档(附带翻译),最后展示代码实现与举例可以直接去看英文文档,也可以看本篇文章,但是更建议去看英文原档。那么废话少说直接开始进行挨个介绍。
213 3
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
514 12
|
11月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
274 0
|
11月前
|
存储 编译器 C语言
关于string的‘\0‘与string,vector构造特点,反迭代器与迭代器类等的讨论
你真的了解string的'\0'么?你知道创建一个string a("abcddddddddddddddddddddddddd", 16);这样的string对象要创建多少个对象么?你知道string与vector进行扩容时进行了怎么的操作么?你知道怎么求Vector 最大 最小值 索引 位置么?
265 0
|
11月前
|
存储 编译器 程序员
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。
434 0
|
编译器 C++
类和对象(中 )C++
本文详细讲解了C++中的默认成员函数,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载和取地址运算符重载等内容。重点分析了各函数的特点、使用场景及相互关系,如构造函数的主要任务是初始化对象,而非创建空间;析构函数用于清理资源;拷贝构造与赋值运算符的区别在于前者用于创建新对象,后者用于已存在的对象赋值。同时,文章还探讨了运算符重载的规则及其应用场景,并通过实例加深理解。最后强调,若类中存在资源管理,需显式定义拷贝构造和赋值运算符以避免浅拷贝问题。