• 【STL】容器 - string的使用


    目录

    一.string类

    二.string类常用接口

    0.静态成员变量npos

    1.构造函数

    2.赋值运算符重载

    3.逐个字符遍历:[]重载与at

     3.0.范围for

    4.迭代器(正向/反向/正向常量/反向常量迭代器)

    5.追加字符/字符串:push_back、append、operator+=

    6.capacity(容量,不包括\0所占空间),max_size,reserve,resize

    7.assign赋值,insert插入,erase删除,replace替换

    8.c_str,给C库提供的接口

    9.find、rfind、substr

    10. find_first_of、find_last_of、find_first_not_of、find_last_not_of


    前言:什么是STL?

    STL(standard template libaray)意为标准模板库,是C++标准库的重要组成部分

    不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架

    一.string类

    string类是basic_string类模板使用char实例化的一个模板类,专门用来处理字符/字符串类型,但注意,不能操作多字符或者变长字符的序列,使用时必须包含

    二.string类常用接口

    0.静态成员变量npos

    static const size_t npos = -1;
    

    npos是无符号整型,定义为-1,也就是无符号整形的最大值4294967295,使用时加上类域 string::npos

    1.构造函数

    1. void test_string1()
    2. {
    3. //1.string();
    4. cout << "1." << endl;
    5. string s1;
    6. cout << s1 << endl;
    7. //2.string(const char* s)
    8. cout << "2." << endl;
    9. string s2("hello world!!!");
    10. cout << s2 << endl;
    11. //3.string(const string& str)
    12. cout << "3." << endl;
    13. string s3(s2);
    14. cout << s3 << endl;
    15. //4.string(const string& str, size_t pos, size_t len = npos)
    16. cout << "4." << endl;
    17. string s4(s3, 6, 4);
    18. cout << s4 << endl;
    19. string s5(s3, 6, 20);
    20. cout << s5 << endl;
    21. string s6(s3, 6);
    22. cout << s6 << endl;
    23. //5.string(const char* s, size_t n);
    24. cout << "5." << endl;
    25. string s7("hello world", 4);
    26. cout << s7 << endl;
    27. //6.string(size_t n, char c)
    28. cout << "6." << endl;
    29. string s8(5, 'm');
    30. cout << s8 << endl;
    31. //7.迭代器版本
    32. cout << "7." << endl;
    33. string s9("helloooooo");
    34. string s10(s9.begin(), s9.end() - 5);
    35. cout << s10 << endl;
    36. }

    2.赋值运算符重载

    1. void test_string2()
    2. {
    3. //1.string& operator=(const string& str)
    4. cout << "1." << endl;
    5. string s1("hello world!");
    6. string s2("hello string!");
    7. s1 = s2;
    8. cout << s1 << endl;
    9. //2.string& operator=(const char* s)
    10. cout << "2." << endl;
    11. string s3("ni hao");
    12. s3 = "hello";
    13. cout << s3 << endl;
    14. //3.string& operator=(char c)
    15. cout << "3." << endl;
    16. string s4("hhhhhh");
    17. s4 = 'h';
    18. cout << s4 << endl;
    19. }

    3.逐个字符遍历:[]重载与at

    1. void test_string3()
    2. {
    3. //char& operator[](size_t pos)
    4. cout << "1." << endl;
    5. string s1("helloworld!");
    6. for (size_t i = 0; i < s1.size(); i++)
    7. {
    8. cout << s1[i] << " ";
    9. }
    10. cout << endl;
    11. //const char& operator[](size_t pos)
    12. cout << "2." << endl;
    13. const string s2("helloworld!");
    14. for (size_t i = 0; i < s2.size(); i++)
    15. {
    16. cout << s2[i] << " ";
    17. }
    18. cout << endl;
    19. //char& at(size_t pos)
    20. cout << "3." << endl;
    21. const string s3("helloat");
    22. for (size_t i = 0; i < s3.size(); i++)
    23. {
    24. cout << s3.at(i) << " ";
    25. }
    26. cout << endl;
    27. //const char& at(size_t pos) const
    28. cout << "4." << endl;
    29. const string s4("helloat");
    30. for (size_t i = 0; i < s4.size(); i++)
    31. {
    32. cout << s4.at(i) << " ";
    33. }
    34. cout << endl;
    35. }

     3.0.范围for

    1. void test_for()
    2. {
    3. string s("hello world!!");
    4. for (auto ch : s)
    5. {
    6. cout << ch << " ";
    7. }
    8. cout << endl;
    9. }

     范围for遍历的底层实际就是迭代器,可以从汇编角度观察到

    4.迭代器(正向/反向/正向常量/反向常量迭代器)

    1. void test_string4()
    2. {
    3. //正向迭代器 - iterator
    4. //[s.begin(),s.end()) - 左闭右开
    5. cout << "1." << endl;
    6. string s1("hello iterator");
    7. string::iterator it = s1.begin();
    8. while (it != s1.end())
    9. {
    10. cout << *it << " ";
    11. it++;
    12. }
    13. cout << endl;
    14. //反向迭代器 - reverse_iterator
    15. //(s.rend(),s.rbegin()] - 左开右闭
    16. cout << "2." << endl;
    17. string s2("hello reverse_iterator");
    18. string::reverse_iterator rit = s2.rbegin();
    19. while (rit != s2.rend())
    20. {
    21. //正/反向迭代器可以通过it修改内容
    22. *rit = 'x';
    23. cout << *rit << " ";
    24. rit++;
    25. }
    26. cout << endl;
    27. cout << s2 << endl;
    28. //常量迭代器 - const_iterator
    29. cout << "3." << endl;
    30. const string s3("hello const_iterator");
    31. //auto cit = s3.begin();自动推导 begin返回什么auto就是什么
    32. string::const_iterator cit = s3.begin();
    33. while (cit != s3.end())
    34. {
    35. cout << *cit << " ";
    36. cit++;
    37. }
    38. cout << endl;
    39. //反向常量迭代器 - const_reverse_iterator
    40. cout << "4." << endl;
    41. const string s4("hello const_reverse_iterator");
    42. string::const_reverse_iterator crit = s4.rbegin();
    43. while (crit != s4.rend())
    44. {
    45. cout << *crit << " ";
    46. crit++;
    47. }
    48. cout << endl;
    49. }

    5.追加字符/字符串:push_back、append、operator+=

    1. void test_string5()
    2. {
    3. cout << "1." << endl;
    4. string s1("hello push_back");
    5. s1.push_back('a');
    6. cout << s1 << endl;
    7. cout << "2." << endl;
    8. string s2("hello append");
    9. s2.append("aaaaa");
    10. cout << s2 << endl;
    11. cout << "3." << endl;
    12. string s3("hello operator+=");
    13. s3 += "hehe";
    14. s3 += 'a';
    15. cout << s3 << endl;
    16. cout << "4." << endl;
    17. string s4("hello");
    18. s4.append(s3.begin(), s3.end() - 5);
    19. cout << s4 << endl;
    20. }

    6.capacity(容量,不包括\0所占空间),max_size,reserve,resize

    1. void test_string7()
    2. {
    3. cout << "1." << endl;
    4. string s1("hello");
    5. cout << s1.max_size() << endl;
    6. cout << s1.capacity() << endl;
    7. //查看vs下的扩容机制
    8. cout << "查看vs下的扩容机制:" << endl;
    9. size_t sz = s1.capacity();
    10. for (size_t i = 0; i < 100; i++)
    11. {
    12. s1.push_back('a');
    13. if (sz != s1.capacity())
    14. {
    15. sz = s1.capacity();
    16. cout << "capacity:" << sz << endl;
    17. }
    18. }
    19. cout << "2." << endl;
    20. string s2("aaaaaaaaaaaaaaaaa");
    21. cout << "reserve之前capacity:" << s2.capacity() << endl;
    22. s2.reserve(1000);//开空间
    23. cout << "reserve之后capacity:" << s2.capacity() << endl;
    24. s2.resize(1000,'x');//开空间+初始化
    25. cout << "resize之后capacity:" << s2.capacity() << endl;
    26. }

    注意:空间只可扩容不可缩小,reverse或者resize开出去的空间多大就是多大,例如第一次reverse(1000)第二次reverse(500)由于第二次比第一次小,空间就按照第一次来算 

    7.assign赋值,insert插入,erase删除,replace替换

    1. void test_string8()
    2. {
    3. cout << "1." << endl;
    4. string s1;
    5. s1.assign("hehe");
    6. cout << s1 << endl;
    7. cout << "2." << endl;
    8. string s2("hello insert");
    9. s2.insert(1, " OH! ");//在pos为1的位置后插入字符串
    10. cout << s2 << endl;
    11. //iterator insert (const_iterator p, char c);
    12. s2.insert(s2.begin(), 'K');
    13. cout << s2 << endl;
    14. s2.erase(0, 1);//在0位置向后删除1个字符
    15. s2.erase(s2.begin() + 2);
    16. cout << s2 << endl;
    17. cout << "3." << endl;
    18. string s3("helloworld");
    19. string s4("zsl");
    20. s3.replace(0, 5, s4);//将0~5替换成s4
    21. cout << s3 << endl;
    22. }

    注意:尽量少使用插入,删除,替换这些接口,因为底层实现是要大量挪动数据的,时间复杂度较高 

    8.c_str,给C库提供的接口

    1. void test_string9()
    2. {
    3. string s1("string.cpp");
    4. FILE* p = fopen(s1.c_str(), "r");
    5. assert(p);
    6. char ch = 0;
    7. while (ch != EOF)
    8. {
    9. ch = fgetc(p);
    10. cout << ch;
    11. }
    12. cout << endl;
    13. s1 += '\0';
    14. s1 += "hehehe";
    15. cout << s1 << endl;//以size为结束标准
    16. cout << s1.c_str() << endl;//以'\0'为结束标准
    17. }

    许多软件的底层使用C语言实现,因为C++兼容C,使用C实现接口,C、C++都可以使用。

    例如:fopen是C语言标准库提供的接口,参数不认识string这样的类,所以传参一般要传字符串的首字符地址,就可以使用c_str()这个接口将string类转换为地址,返回值为const char*

    9.find、rfind、substr

    1. void test_string10()
    2. {
    3. //查找文件后缀
    4. //从前向后找
    5. cout << "1." << endl;
    6. string s1("string.cpp");
    7. size_t pos1 = s1.find(".");
    8. cout << s1.substr(pos1) << endl;
    9. //从后向前找
    10. cout << "2." << endl;
    11. string s2("hello.world.cpp");
    12. size_t pos2 = s2.rfind(".");
    13. cout << s2.substr(pos2) << endl;
    14. }

    注意:find()中传的参数要全部匹配上才可以,与下一条(10.)有明显区别

    10. find_first_of、find_last_of、find_first_not_of、find_last_not_of

    1. void test_string11()
    2. {
    3. cout << "1." << endl;
    4. string s1("hello,This,is,my,world!");
    5. size_t pos1 = 0;
    6. while (1)
    7. {
    8. pos1 = s1.find_first_of("l,!");
    9. if (pos1 == string::npos)
    10. break;
    11. s1[pos1] = '*';
    12. cout << s1 << endl;
    13. }
    14. cout << "2." << endl;
    15. string s2("hello,This,is,my,world!");
    16. size_t pos2 = 0;
    17. while (1)
    18. {
    19. pos2 = s2.find_first_not_of("l,!");
    20. if (pos2 == string::npos)
    21. break;
    22. s2[pos2] = ',';
    23. cout << s2 << endl;
    24. }
    25. cout << "3." << endl;
    26. string s3("hello,This,is,my,world!");
    27. size_t pos3 = 0;
    28. while (1)
    29. {
    30. pos3 = s3.find_last_of("l,!");
    31. if (pos3 == string::npos)
    32. break;
    33. s3[pos3] = '*';
    34. cout << s3 << endl;
    35. }
    36. }

    find_first_of、find_last_of:只要有一个匹配上即可

    find_first_not_of、find_last_not_of:只要不是这些字符的任意一个即可

    除此之外string支持比较大小、支持加法、operator>>/<<,以上为string类使用的高频接口,只讲解了重点,如果想要更全面细致了解,请到下面官方网址查阅官方资料

    string - C++ Reference

  • 相关阅读:
    leetcode: 322. 零钱兑换-dp
    智慧校园烟火识别及预警解决方案,保障校园消防安全
    111.(leaflet篇)leaflet椭圆采集
    Java 一台机器搭建多个tomcat,运行不同的程序
    NC21587:回文子序列计数(dp)
    java毕业设计茶叶企业管理系统Mybatis+系统+数据库+调试部署
    研究铜互连的规模能扩大到什么程度
    【古谷彻】算法模板(更新ing···)
    如何判断一段程序是否是裸机程序?
    软件测试面试题之易错题
  • 原文地址:https://blog.csdn.net/Hello_World_213/article/details/126373633