String类

 > 作者简介:დ旧言~,目前大二,现在学习Java,c,c++,Python等
> 座右铭:松树千年终是朽,槿花一日自为荣。

> 目标:熟悉string库

> 毒鸡汤:人生就像一场旅行,不在乎目的地,而在乎沿途的风景以及看风景的心情。

> 望小伙伴们点赞收藏✨加关注哟 

前言

        学习这个板块可能有点头疼,因为太多的函数,学完都不知道学的是啥,正常。所以博主介绍一个学习c++的网站,这个网站也是c++创始人所写的,方便大家学习c++,太良心啦。

官网:cplusplus.com - The C++ Resources Network

String类_第1张图片

 ⭐主体

        基于C语言的字符串,用起来是在复杂,稍不留神可能还会越界访问。为了操作方便,c++产生了string库,便于操作字符串。咱们就按照c++给的官网学习string库,具体分为六大板块,分别为:Member functions(成员函数),Iterators(迭代器),Capacity(容量),Element access(元素访问),Modifiers(修改器),String operations (字符串操作)☺️☺️☺️。

String类_第2张图片

Member functions(成员函数)

在这个板块中挺重要的,咱也不是全学,到时候可能真的就是从入门到放弃。

constructor(构造函数)

构造字符串对象,根据使用的构造函数版本初始化其值。

String类_第3张图片

也就是说根据创建的string类来进行赋初始化。

  • str:另一个字符串对象,其值被复制或获取。
  • pos:str中作为子字符串复制到对象的第一个字符的位置。如果这大于str的长度,则抛出out_of_range。注意:str中的第一个字符由值0(而不是1)表示。
  • len:要复制的子字符串的长度(如果字符串较短,则复制尽可能多的字符)。字符串::npos的值表示str结束之前的所有字符。s

那咱们看看这个代码:

#include 
#include 

using namespace std;

int main()
{
    // 无参构造函数
    string s1();

    // 常量字符串构造函数
    string s2("hello world");
    cout << s2 << endl;

    // 拷贝构造函数
    string s3(s2);
    cout << s3 << endl;
    
    // 拷贝构造还可以写成下面这样子
    string s4 = s2;

    //初始化不够 11 > 9
    string s5("hello world", 9);
    cout << s5 << endl;

    return 0;
}

运行结果:

 operator=(赋值函数)

为字符串指定一个新值,替换其当前内容。

这里提供了三种赋值函数:

  • 通过string对象赋值给string对象
  • 通过常量字符串赋值给string对象
  • 通过字符赋值给string对象。
#include 
#include 

using namespace std;

int main()
{
    //通过string对象赋值给string对象
    string s1("hello");
    string s2;
    s2 = s1;
    cout << s2 << endl;

    //通过常量字符串赋值给string对象
    s2 = "world";
    cout << s2 << endl;

    //通过字符赋值给string对象。
    s2 = 'C';
    cout << s2 << endl;
    return 0;
}

 运行结果:

Iterators(迭代器)

        我们在前面浅谈了迭代器,没有细说,今天有机会了,看着迭代器名字刁刁的,本质上还是一种遍历,像我们的for循环,典型的迭代器,咱们先看看最初我们用下标来访问遍历。

        string类是提供了[]运算符重载的,这也就意味着string可以让我们像访问数组一样利用下标来访问元素。

#include 
#include 

using namespace std;

int main()
{
    string s("hello world");

    for (size_t i = 0; i < s.size(); i++)
    {
        cout << s[i] << " ";
    }
    cout << endl;
    
    return 0;
}

运行结果:

利用begin和end实现迭代器

  • begin()函数返回的是string字符串的首位置
  • end()函数返回的是string字符串最后一个位置(即最后一个字符的下一个位置)

String类_第4张图片

咱看看代码:

#include 
#include 

using namespace std;

int main()
{
    string str("hello world");
    string::iterator it = str.begin();
    
    while (it != str.end())
    {
        cout << *it;
        ++it;
    }
    
    cout << endl;
    return 0;
}

运行结果:

范围for实现迭代器

不知道小伙伴还记得auto关键字不,auto可以推导出元素属性(int,char)

咱们看看代码:

#include 
#include 

using namespace std;

int main()
{
    string s("hello world");
    for (auto ch : s)
    {
        cout << ch;
    }
    cout << endl;
    return 0;
}

运行结果:

反向迭代器

这里需要介绍一下rbegin()和rend()这两个函数,这两个函数是用来配合反向迭代器使用的。

  • rbegin()函数返回的是string字符串的最后一个有效字符
  • rend()函数返回的是string字符串的第一个字符的前一个位置。

String类_第5张图片

咱们看看代码:

#include 
#include 

using namespace std;

int main()
{
    string s("hello world");
    string::reverse_iterator rit = s.rbegin();
    while (rit != s.rend())
    {
        cout << *rit;
        rit++;
    }
    cout << endl;
    return 0;
}

运行结果:

const修饰的迭代器

const修饰的迭代器是不可以改变的(只能读不能写)

咱们看看代码:

void Func(const string& s)
{
    string::const_iterator cit = s.begin();
    // 读操作
    while (cit != s.end())
    {
        cout << *cit;
        cit++;
    }
    cout << endl;

    // 不能进行写操作,会报错
    // cit = s.begin();
    // while (cit != s.end())
    // {
    //     (*cit) += 1;
    //     cout << *cit;
    //     cit++;
    // }

}

Capacity(容量)

学习这个板块还是比较简单的,也运用比较广泛的一个板块。

String类_第6张图片

size和length

size函数和length函数本质上是一样的,都是计算元素总个数的。

String类_第7张图片

咱们看看代码:

#include 
#include 

using namespace std;

int main ()
{
    string s("hello world");
    cout << s.size() << endl;
    cout << s.capacity() << endl;
    return 0;
}

运行结果:

  • size是计算字符串的元素个数,除\0
  • capacity是计算字符串的容量,也就是说定义一个string类是有初始容量的

reserve和resize

reserve函数是扩容函数,可以增大capacity的值,

resize其实也是扩容函数,但resize改变的是size的值,当size的值增大时自动触发string的扩容机制从而也增大了capacity的值

resize在增带size值的时候还会对没有字符的位置初始化,如果没有指定初始化内容就默认初始化为’\0’,而reserve不会进行初始化。

String类_第8张图片

咱们看看代码:

#include 
#include 

using namespace std;

int main()
{
    string s("hello");
    cout << s << endl;
    cout << "size:" << s.size() << endl;
    cout << "capacity:" << s.capacity() << endl;
    cout << endl;

    s.reserve(25);
    cout << s << endl;
    cout << "size:" << s.size() << endl;
    cout << "capacity:" << s.capacity() << endl;
    cout << endl;

    s.resize(50, 'A');
    cout << s << endl;
    cout << "size:" << s.size() << endl;
    cout << "capacity:" << s.capacity() << endl;
    cout << endl;
    return 0;
}

运行结果:

String类_第9张图片

max_size

max_size函数是计算字符串可以达到的最大长度。

咱们看看代码:

#include 
#include 

using namespace std;

int main()
{
	std::string str("Test string");
	std::cout << "size: " << str.size() << "\n";
	std::cout << "length: " << str.length() << "\n";
	std::cout << "capacity: " << str.capacity() << "\n";
	std::cout << "max_size: " << str.max_size() << "\n";
	return 0;
}

运行结果:

Element access(元素访问)

这个板块做为了解,知道有就行了。

 at函数

返回对字符串中位置pos处的字符的引用。本质上还是一种遍历。

咱们看看代码:

#include 
#include 

int main()
{
    std::string str("Test string");
    for (unsigned i = 0; i < str.length(); ++i)
    {
        std::cout << str.at(i);
    }
    return 0;
}

运行结果:

这里捏还有很多函数就不再细讲咯,有兴趣老铁们翻翻看看。

String类_第10张图片

Modifiers(修改器)

这个接口重重重重点,这里会讲解插入删除.....

 operator+=插入操作

这种操作本质上是一种赋值运算重载,用起来真的爽,它不仅可以插入新的string对象,还可以插入常量字符串,也可以插入单个字符,我们平时使用最多的方式也是这个方式。

String类_第11张图片

 咱们看看代码:

#include 
#include 

using namespace std;

int main()
{
    string s("hello ");
 
    // 插入常量字符串
    s += "world"; 
    cout << s << endl;
    
    string str("world");
    
    // 插入新的string对象
    s += str; 
    cout << s << endl;
    
    // 插入单个字符
    s += 'A';
    cout << s << endl;
    return 0;
}

运行结果:

 append插入操作

它可以插入字符串,可以插入另一个string对象,而且可以指定n个字符插入,非常多样化。

String类_第12张图片

  咱们看看代码:

#include 
#include 

using namespace std;

int main()
{
    string s("hello ");
    
    // 插入常量字符串
    s.append("world");
    cout << s << endl;

    string str("world");

    // 插入另一个string对象
    s.append(str);
    cout << s << endl;
    return 0;
}

运行结果:

 push_back插入操作

将字符c追加到字符串的末尾,使其长度增加一,也就是说push_back函数只能够尾插入一个字符,不能插入字符串。

  咱们看看代码:

#include 
#include 

using namespace std;

int main()
{
    string s("hello ");
    
    // 插入一个字符
    s.push_back('C');
    cout << s << endl;
    return 0;
}

 运行结果:

 insert插入操作

insert函数可以在任意的指定位置进行插入。

它可以在任意的指定位置

  • 插入一个新的string对象
  • 一个常量字符串
  • 一个常量字符串的n个字符
  • 一个字符
  • 等等....

String类_第13张图片

  咱们看看代码:

#include 
#include 

using namespace std;

int main()
{
    string s("hello");

    // 在下标为0的位置插入一个新的string对象
    string str("hello world");
    s.insert(0, str);
    cout << s << endl;

    // 在下标为0的位置插入一个常量字符串
    s.insert(0, "hello world");
    cout << s << endl;

    // 在下标为0的位置插入一个常量字符串的前3个字符
    s.insert(0, "hello world", 3);
    cout << s << endl;

    // 在下标为0的位置插入一个字符x
    s.insert(0, 1, 'x');
    s.insert(s.begin(), 'x');
    cout << s << endl;

    // 在下标为0的位置插入三个字符x
    s.insert(0, 3, 'x');
    cout << s << endl;

    return 0;
}

 运行结果:

 erase删除操作

擦除字符串的一部分,缩短其长度,本质上erase函数删除任意指定位置的n个字符

String类_第14张图片

   咱们看看代码:

#include 
#include 

using namespace std;

int main()
{
    string s("hello world");

    // 删除下标为3位置的一个字符
    s.erase(3, 1);
    cout << s << endl;

    // 删除以下标为3位置为起点的3个字符
    s.erase(3, 3);
    cout << s << endl;

    // 删除以下标为3位置为起点往后的所有字符
    s.erase(3);
    cout << s << endl;

    return 0;
}

 运行结果:

 pop_back删除操作

擦除字符串的最后一个字符,有效地将其长度减少一个,本质上可以实现string对象的尾删操作。

   咱们看看代码:

#include 
#include 

using namespace std;

int main()
{
    string s("hello world");
    s.pop_back();
    cout << s << endl;
    return 0;
}

  运行结果:

 swap交换操作

实现两个对象之间的交换。

   咱们看看代码:

#include 
#include 

using namespace std;

int main()
{
    string s1("hello world");
    string s2("string");
    s1.swap(s2);

    cout << s1 << endl;
    cout << s2 << endl;
    return 0;
}

  运行结果:

String operations (字符串操作)

        这个板块主要讲解的是,字符串的查找呀,返回值。在许多的题中都运用这块知识,望大家好好体会叭。

String类_第15张图片

 c_str返回值

返回一个指向数组的指针,该数组包含一个以null结尾的字符序列(即C字符串),咱们可以用这个函数实现返回string对象对应的char * 指针

   咱们看看代码:

//将string对象的内容通过strcpy函数拷贝到字符数组当中
#include 
#include 
#include 

using namespace std;

int main()
{
    string str("hello world");
    char* cstr = new char[str.size() + 1];
    strcpy(cstr, str.c_str());
    cout << cstr << endl;
    return 0;
}

  运行结果:

 find查找

查找string对象、常量字符串或者是一个字符,并且可以设定pos值来规定查找的起始位置,默认从0下标开始查找。

String类_第16张图片

   咱们看看代码:

// string::find
#include        // std::cout
#include          // std::string

int main()
{
    std::string str("There are two needles in this haystack with needles.");
    std::string str2("needle");

    // different member versions of find in the same order as above:
    std::size_t found = str.find(str2);
    if (found != std::string::npos)
        std::cout << "first 'needle' found at: " << found << '\n';

    found = str.find("needles are small", found + 1, 6);
    if (found != std::string::npos)
        std::cout << "second 'needle' found at: " << found << '\n';

    found = str.find("haystack");
    if (found != std::string::npos)
        std::cout << "'haystack' also found at: " << found << '\n';

    found = str.find('.');
    if (found != std::string::npos)
        std::cout << "Period found at: " << found << '\n';

    // let's replace the first needle:
    str.replace(str.find(str2), str2.length(), "preposition");
    std::cout << str << '\n';

    return 0;
}

  运行结果:

 find查找

rfind是倒着查找。find函数和rfind函数的区别就是查找方向不同。

String类_第17张图片

这里就不再上代码咯。

 substr

返回string字符串的一个任意子串

咱们看看代码:

#include 
#include 

using namespace std;

int main()
{
    string s1("hello world");
    
    // 取出子串"world"
    string s2 = s1.substr(6, 5);
    cout << s2 << endl;
    return 0;
}

 运行结果:

到这里还有很多函数没有介绍:

String类_第18张图片

可以去看看官网中它们的使用方法。

结束语

       今天内容就到这里啦,时间过得很快,大家沉下心来好好学习,会有一定的收获的,大家多多坚持,嘻嘻,成功路上注定孤独,因为坚持的人不多。那请大家举起自己的小说手给博主一键三连,有你们的支持是我最大的动力,回见。

你可能感兴趣的:(c++)