• 【C++】 —— string的使用


    前言

            string类虽然不在STL的容器中,但string类十分重要,string类是对字符串的存储和相关操作。

            basic_string

            std::basic_string类是C++的一个模版类,它支持多种字符类型。

    1. char :用于表示一个字节的字符,使用ASCII编码。
    2. wchar_t :用于表示宽字符,可以支持更广泛的字符集。
    3. char8_t :用于表示8位的Unicode字符(UTF-8)。
    4. char16_t :用于表示16位的Unicode字符(UTF-16)。
    5. char32_t :用于表示32位的Unicode字符(UTF-32)。

    basic_string 实例化出来的4种类型:

    1. string
    2. wstring
    3. u16string
    4. u32string

            string类是basic_string模版类的一个实例,它使用char来实例化basic_string模版类,并使用char_traits和allocator 作为basic_string的默认参数。

    一、string类

    1、string类是表示字符序列的类。

    2、标准的字符串类提供了对此对象的支持,其接口类似于标准字符容器的接口,但是添加了专门用于操作单字节字符字符串的设计特性。

    3、string类封装了字符数组,并提供了一系列成员函数来执行字符串的创建、修改、连接、查找、替换等操作。

            string类出现实际上是比STL要早的,后来才分入STL库里面;所以,string一开始设计比较冗余,有很多重复功能的接口;我们没必要记住所有的接口,只需将核心接口记住并熟练使用就好啦;(如果遇到陌生的接口,直接查看文档就好了)。

    string类文档

    二、string默认成员函数

            2.1、构造函数

    先来看一下C++库里面string的构造函数。

    1、string();

            这是没有参数的构造函数(也就是默认构造函数),就是在创建string类对象时不需要传参数。

    1. #include
    2. #include
    3. using namespace std;
    4. void test()
    5. {
    6. string s1;
    7. }
    8. int main()
    9. {
    10. test();
    11. return 0;
    12. }

    2、string(const char* s);

            在创建string类对象时,传字符串(指针/字符数组),进行类对象的初始化。

    使用:用字符串来初始化对象。

    1. void test()
    2. {
    3. string s1; //string();
    4. string s2("I Love You"); //string(const char* s);
    5. }

    3、string(const char* s, size_t n);

            与上面的构造函数不同的时,在传字符串指针的时,多一个参数n。

    使用:用字符数组的前n个字符来初始化string类对象。

    1. void test()
    2. {
    3. string s1; //string();
    4. string s2("I Love You"); //string(const char* s);
    5. string s3("I Love You", 6); //string(const char* s, size_t n);
    6. }

    可以通过调试来看对象s1,s2,s3的值

    4、string(const string& str);

            在创建string类对象,传同为string类类型的对象进行对象的初始化(也就是拷贝构造函数)。

    使用:通过同类型的对象来初始化;

    1. void test()
    2. {
    3. string s1; //string();
    4. string s2("I Love You"); //string(const char* s);
    5. string s3("I Love You", 6); //string(const char* s, size_t n);
    6. string s4(s2); // string(const string& str);
    7. }

    5、string(const string& str, size_t pos, size_t len=npos);

            与拷贝构造不同的时,这个构造函数,还需要多传两个参数pos和len;

    使用:用str中的第pos个位置后面len个字符进行初始化对象。

    1. void test()
    2. {
    3. string s1; //string();
    4. string s2("I Love You"); //string(const char* s);
    5. string s3("I Love You", 6); //string(const char* s, size_t n);
    6. string s4(s2); // string(const string& str);
    7. string s5(s2, 2, 4); //string(const string& str, size_t pos, size_t len=npos);
    8. }

    6、string(size_t n, char ch);

            创建string类对象,并将其内容设置成n个ch。

    1. void test()
    2. {
    3. string s1; //string();
    4. string s2("I Love You"); //string(const char* s);
    5. string s3("I Love You", 6); //string(const char* s, size_t n);
    6. string s4(s2); // string(const string& str);
    7. string s5(s2, 2, 4); //string(const string& str, size_t pos, size_t len=npos);
    8. string s6(6, 'H'); //string(size_t n, char ch);
    9. }

    7、

            C++文档中最后一个构造函数,涉及到迭代器,这里先不介绍,后面再使用。

            2.2、析构函数

            析构函数没有函数重载,就不过多叙述。

            2.3、赋值运算符重载

    1、string& operator= (const string& str);

            使用:这个就是对于两个已经存在的string类类型对象,进行赋值操作。

    1. void test1()
    2. {
    3. string s1;
    4. string s2("Hello World");//拷贝构造
    5. s1 = s2;//赋值运算符重载
    6. }

    2、string& operator= (const char* s);

            使用:将一个字符串赋值给一个已经存在的string类类型对象。

    1. void test1()
    2. {
    3. string s1;
    4. string s2("Hello World");//拷贝构造
    5. s1 = s2;//赋值运算符重载
    6. string s3;
    7. s3 = "I Love ";//operator= (const char* s);
    8. }

    3、string& operator= (char ch);

            使用:将一个字符赋值给一个已经存在的string类类型对象。

    1. void test1()
    2. {
    3. string s1;
    4. string s2("Hello World");//拷贝构造
    5. s1 = s2;//赋值运算符重载
    6. string s3;
    7. s3 = "I Love ";//operator= (const char* s);
    8. string s4;
    9. s4 = 'c';//operator= (char ch);
    10. }

    调试看一下赋值结果:

    三、string其他成员函数

            3.1、Capacity

    这里就看几个常用的(size、lengh、resize、capacity、clear和empty)。

    1、size*

            size就是返回string对象中的字符(数据)个数(也就是字符串的长度)。

    2、lengh

            lengh和size一样,都是计算string对象中字符串的长度。

    3、resize*

            resize是设置string对象中字符串的内容,(如果n要小于size就将字符串数据个数设为n)如果n大于size,(空间不够就扩容)设置size后面的字符内容。如果给了参数c就设置成 c;如果没有给参数c,就默认设置成'\0'。

    4、capacity*

            capacity 返回string对象中可用空间的大小(就像动态顺序表中capacity一样)。

    5、clear*

            clear是清理string中字符串的内容,让string对象中字符串变为空,并修改对象中size的值。

    6、empty*

            empty判断string对象是否为空;为空就返回true,否则返回false。

    7、reserve*

            

            reserve是设置string的空间大小,如果传参n比capacity大就扩容;如果小,不一定会缩小容量。

    1. void test2()
    2. {
    3. string s1("I Love You !!!");
    4. //size 返回s1中字符串数据个数
    5. cout << "size = " << s1.size() << endl;
    6. //lengh 返回s1中字符串长度
    7. cout << "lengh = " << s1.length() << endl;
    8. //capacity 返回s1中可用空间大小
    9. cout << "capacity = " << s1.capacity() << endl;
    10. //设置s1中数据个数
    11. s1.resize(10);
    12. cout << s1 << endl;
    13. s1.resize(20, 'x');
    14. cout << s1 << endl;
    15. //清理s1中字符串内容,使其变成空
    16. s1.clear();
    17. cout << s1 << endl;
    18. //empty 判断s1中字符串是否为空
    19. cout << s1.empty() << endl;
    20. }

            3.2、Element access 数据访问

            Element access 就是元素访问,(访问字符串中的数据)。

            这里就主要看 operator[] 和at;

            除了这样访问元素,还可以通过迭代器就行访问(下面在迭代器内容进行使用)。

    1、operator[]  *

            operator[] 库里面实现了两个,一个用于普通对象的元素访问(可读可写),另一个就用于const修饰的对象的元素访问(只读)。

            有了operator[] 这个运算符重载的函数,我们就可以像访问字符数组那样去通过下标访问string类型对象。

    2、at

            at这个函数是传递一个参数pos,获得string对象中字符串下标为pos的字符。(使用起来和operator[]一样)。

    1. void test3()
    2. {
    3. string s1("Hello world");
    4. for (int i = 0; i < s1.size(); i++)
    5. {
    6. s1[i]++; //普通对象调用char& operator[](size_t pos); 可以进行修改
    7. cout << s1[i] << " ";
    8. }
    9. cout << endl;
    10. const string s2("Hello World");
    11. for (int i = 0; i < s2.size(); i++)
    12. {
    13. //s2[i]++; //err
    14. //const修饰的对象调用const char& operator[](size_t pos) cosnt; 不能进行修改
    15. cout << s2[i] << " ";
    16. }
    17. cout << endl << endl;
    18. string s3("Hello world");
    19. for (int i = 0; i < s3.size(); i++)
    20. {
    21. s3.at(i)++; //普通对象调用char& at(size_t pos); 可以进行修改
    22. cout << s3.at(i) << " ";
    23. }
    24. cout << endl;
    25. const string s4("Hello World");
    26. for (int i = 0; i < s4.size(); i++)
    27. {
    28. //s4.at[i]++; //err
    29. //const修饰的对象调用const char& at(size_t pos) cosnt; 不能进行修改
    30. cout << s4.at(i) << " ";
    31. }
    32. cout << endl;
    33. }

            3.3、Modifiers

            Modifiers ,库里面提供了以下这些函数,对string对象中字符串进行设置(修改)

    1、operator+=   *

            库里面实现了三个+=运算符重载函数,我们在使用时就可以像内置类型那样+=;

    这里可以+=一个string类类型对象、字符串(字符数组)或者一个字符。

    1. void test4()
    2. {
    3. string s1("hello ");
    4. string s2("world ");
    5. s1 += s2;
    6. cout << s1 << endl;
    7. char str[] = "ever";
    8. s1 += str;
    9. cout << s1 << endl;
    10. s1 += 'o';
    11. s1 += 'n';
    12. s1 += 'e';
    13. cout << s1 << endl;
    14. }

    2、append

            库里面实现的append感觉有点冗余;

            append可以增加string类型对象(也可以是其中的一部分)、字符串(可以是其中的一部分)、n个字符;传参也可以是迭代器。

    1. void test5()
    2. {
    3. string s1("hello ");
    4. string s2("world ");
    5. //s1.append(s2); 也可以直接添加s2的全部
    6. s1.append(s2, 1, 3);
    7. //从下标为1的位置开始,添加后面3个字符
    8. cout << s1 << endl;
    9. s1.append("everone");
    10. //s1.append("everone",4);
    11. //也可以这样,只添加前4个字符
    12. cout << s1 << endl;
    13. s1.append(3, 'x');
    14. //添加3个字符 'x'
    15. cout << s1 << endl;
    16. }

    3、push_back

    push_back就是在string对象后面添加一个字符。(比较简单就不测试了)。

    4、assgin

            assgin是设置string类对象的内容,(可以用同类型对象来设置(也可以是一部分)、也可以用字符串设置(或者其中一部分)、也可以将strng对象内容设置成n个字符;(也可以传迭代器))。

    1. void test5()
    2. {
    3. string s1("hello ");
    4. string s2("world ");
    5. //s1.append(s2);
    6. s1.assign(s2, 1, 3);
    7. cout << s1 << endl;
    8. s1.assign("everone");
    9. //s1.append("everone",4);
    10. cout << s1 << endl;
    11. s1.assign(3, 'x');
    12. cout << s1 << endl;
    13. }

    5、insert

            insert与assgin不同,要比assgin多一个参数,这个参数pos就决定了从string对象中字符串哪个位置开始设置字符串的内容。

    1. void test5()
    2. {
    3. string s1("hello ");
    4. string s2("world ");
    5. //s1.append(s2);
    6. s1.insert(3, s2, 1, 3);
    7. cout << s1 << endl;
    8. s1.insert(8, "everone");
    9. //s1.append("everone",4);
    10. cout << s1 << endl;
    11. s1.insert(15, 3, 'x');
    12. cout << s1 << endl;
    13. }

    6、erase

            erase是删除string对象中字符串的数据,(删除pos位置后面的len和字符);如果不传参就是全部删除(如果只是不传len的参数,就默认删除pos后面所有的数据)。

    1. void test6()
    2. {
    3. string s1("hello world !!!");
    4. cout << s1 << endl;
    5. s1.erase(11, 3);
    6. cout << s1 << endl;
    7. s1.erase(5);
    8. cout << s1 << endl;
    9. s1.erase();
    10. cout << s1 << endl;
    11. }

    7、replace

    replace 替换string对象字符串中的数据;

    函数的前两个参数,就是指需要替换的位置(pos位置后面的len个字符)。

            可以替换成string类类型对象(也可以是一部分)、字符串(也可以是一部分)、n个字符或者迭代器指向的区间。

    1. void test7()
    2. {
    3. string s1("Hello World ");
    4. string s2("everone");
    5. cout << s1 << endl;
    6. s1.replace(6, 5, s2);
    7. cout << s1 << endl;
    8. s1.replace(6, 5, "I Love");
    9. cout << s1 << endl;
    10. s1.replace(6, 5, 3, '*');
    11. cout << s1 << endl;
    12. }

    8、swap

            swap是库里面实现的一个函数(交换两个string类类型对象)。

    1. void test8()
    2. {
    3. string s1("hello world");
    4. string s2("I Love you");
    5. cout << "s1: " << s1 << endl;
    6. cout << "s2: " << s2 << endl;
    7. s1.swap(s2);
    8. cout << "s1: " << s1 << endl;
    9. cout << "s2: " << s2 << endl;
    10. }

            3.4、String operations 字符串操作

            字符串操作,主要操作有返回字符串指针、查找、拷贝、获得子串等。(这里就使用其中的一部分)。

    1、c_str   *

            c_str返回string对象里的字符串指针。(需要注意的就是返回的指针是const修饰的,必须用const指针接受)。

    1. void test9()
    2. {
    3. string s1("Hello World");
    4. const char* s = s1.c_str();
    5. cout << s << endl;
    6. }

    2、find   *

            find查找, 在string对象里查找指定字符(string类类型对象、字符串、字符),也可以指定区间进行查找。找到就返回下标;没有找到返回npos。

    1. void test9()
    2. {
    3. string s1("Hello World");
    4. string s2("Hello");
    5. size_t f1 = s1.find(s2);
    6. size_t f2 = s1.find("Love");
    7. size_t f3 = s1.find('o');
    8. cout << f1 << endl;
    9. cout << f2 << endl;
    10. cout << f3 << endl;
    11. }

    3、substr   *

            substr获得string对象字符串中的子串。这结合上面的find,

    实现将一个网址的协议、域名以及资源分开。

    1. void test10()
    2. {
    3. string s1("https://blog.csdn.net/LH__1314?type=blog");
    4. size_t f1 = s1.find("://", 0);
    5. string protocol = s1.substr(0, f1);
    6. size_t f2, f3;
    7. f2 = s1.find('/', f1 + 3);
    8. string domain = s1.substr(f1 + 3, f2 - (f1 + 3));
    9. string resource = s1.substr(f2 + 1);
    10. cout << protocol.c_str() << endl;
    11. cout << domain.c_str() << endl;
    12. cout << resource.c_str() << endl;
    13. }

            3.5、Inerator

            inerator就是所谓的迭代器,在string中迭代器作用没有那么大,(甚至可以将它理解为指针(但迭代器不是指针))。

    在使用这些函数之前,要先知道一种类型,迭代器 iterator

    string::iterator it;

    因为在其他容器里也存在迭代器,所以定义时要指定类域。

    1、begin、end

            这里的两个函数返回的都是迭代器,begin返回的是起始位置,end返回的是终止位置。

            这里库里面还实现了const修饰的函数,const修饰的迭代器类型有所不同

    string::const_iterator it;

    这里直接使用:

    1. void test11()
    2. {
    3. string s1("I Love You");
    4. string::iterator it = s1.begin();
    5. while (it != s1.end())
    6. {
    7. cout << *it << " ";
    8. it++;
    9. }
    10. cout << endl;
    11. }

    2、范围for

    有了迭代器,我们就可以实现一种语法 范围for

    1. void test11()
    2. {
    3. string s1("I Love You");
    4. for (auto ch : s1)
    5. {
    6. cout << ch << " ";
    7. }
    8. }

    到这里,string类的基本使用就结束了。

    感谢各位大佬支持并指出问题,

                            如果本篇内容对你有帮助,可以一键三连支持以下,感谢支持!!!

  • 相关阅读:
    [极客大挑战 2019]Http 1
    Python 程序性能测试方法
    [附源码]Python计算机毕业设计本科生外出请假管理信息系统
    SQL Server底层架构技术对比
    22.10.20补卡 CF-1749C
    ZZNUOJ_C语言的算法「零基础9讲」和「题库150例练习」-总目录(更新中)
    js实现字符串转json对象的四种方法
    并发编程八 Collections之Map&List&Set
    一个C#跨平台的机器视觉和机器学习的开源库
    VSCode 环境配置原理
  • 原文地址:https://blog.csdn.net/LH__1314/article/details/142283184