C++标准模板库--string类

在C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要自己管理,稍有不慎可能还会越界访问。为了让字符串操作符合面向对象的思想,C++标准模板库定义了string类。

标准库中的string类

  1. 字符串是表示字符序列的类
  2. 标准的字符串类提供了对此类对象的支持,其接口类似标准字符容器的接口,但添加了专门用于操作单字节字符串的设计特性
  3. string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型)
  4. string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数
  5. 这个类独立于所使用的编码来处理字节

PS:使用string类要using namespace std

总结:

  1. string是表示字符串的字符串类
  2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
  3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator> string;
  4. 不能操作多字节或者边长字符的序列
string类的常用接口说明
1. string类对象的常见构造
函数名称功能说明
string()构造空的string类对象,即空字符串
string(const char* s)用c语言的字符串来构造string类对象
string(size_t n, char c )string类对象中包含n个字符串c
string(const string& s)拷贝构造函数
  1 #include<iostream>
  2 #include<string>
  3 using namespace std;
  4 int main(){
  5     
  6     string str1;
  7     string str2("asdfasdf");
  8     string str3(10, 'c');
  9     string str4(str2);
 10     std::cout << str1 << std::endl;
 11     std::cout << str2 << std::endl;
 12     std::cout << str3 << std::endl;
 13     std::cout << str4 << std::endl;
 14     return 0;
 15 }

在这里插入图片描述

2. string类对象的容量操作
函数名称功能说明
size返回字符串有效字符长度
length返回字符串有效字符长度
capacity返回空间总大小
empty检测字符串是否为空字符串,是返回true,否则返回false
clear清空有效字符
reserve为字符串预留空间
resize将有效字符的个数改成n个,多出的空间用字符c填充
  1 #include<iostream>
  2 #include<string>
  3 using namespace std;
  4 
  5 int main(){
  6 
  7     string str("hello world");
  8     cout <<"str的有效字符个数:" << str.size() << endl;
  9     cout << "str的有效字符个数:" << str.length() << endl;
 10     cout << "str的总空间大小:" << str.capacity() << endl;
 11 
 12     // string类对象支持直接使用cin和cout进行输入和输出
 13     cout << str << endl;
 14 
 15     // 将str中有效字符串清空,注意清空时只是将size清0,不改变底层空间的大小
 16     str.clear();
 17     cout <<"使用clear函数之后的size:" << str.size() << endl;
 18     cout << "使用clear函数之后的总空间大小 " << str.capacity() << endl;
 19 
 20     // 将str中有效字符个数增加到15个,多出位置用't'进行填充
 21     str.resize(10, 't');
 22     cout <<"使用resize(10, \'t\')的size:" <<  str.size() << endl;
 23     cout << str.capacity() << endl;
 24     cout << str << endl;
 25 
 26     // 将str中有效字符个数增加到15个,多出的位置用缺省值'\0'进行填充
 27     str.resize(15);
 28     cout << "resize(15)" << endl;
 29     cout << str.size() << endl;
 30     cout << str.capacity() << endl;
 31     cout << str << endl;
 32 
 33     // 将str中有效字符个数缩小到5个
 34     str.resize(5);
 35     cout << "resize(5)" << endl;
 36     cout << str.capacity() << endl;
 37     cout << str << endl;
 38     return 0;
 39 }

在这里插入图片描述

看到这里,或许会有小伙伴会问,如果使用reserve函数,是否会改变string中有效元素个数呢?reserve参数小于string的底层空间大小时,是否会将空间缩小呢?在不同的编译器有不同结果

  1 #include<iostream>
  2 #include<string>
  3 using namespace std;
  4 int main(){
  5     
  6     string str;
  7     // 测试reserve是否会改变string中有效元素个数
  8     str.reserve(100);
  9     cout << str.size() <<endl;
 10     cout << str.capacity() <<endl;
 11     
 12     // 测试reserve参数小于string的底层空间大小时,是否会将空间缩小
 13     str.reserve(50);
 14     cout << "参数小于底层空间大小" << endl;
 15     cout << str.size() << endl;
 16     cout << str.capacity() << endl;
 17     return 0;
 18 }

在这里插入图片描述

在这里插入图片描述

  1. size()与length()方法底层实现原理完全相同,引入size()的原因时是为了与其他容器的接口保持一致,一般情况下都是用size()
  2. clear()只是将string中有效字符串清空,不改变底层空间大小
  3. reserve(size_t n)resize(size_t n, char c)都是字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符串c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果元素个数减少,底层空间总大小不变
  4. reserve(size_t rcs_arg = 0):为string预留空间,不改变有效元素个数,当reserve的参数小于string底层空间总大小时,在vs中不会改变容量大小,在g++里面会改变容量大小
3. string类对象的访问及遍历操作
函数名称功能说明
operator[]返回pos位置的字符,const string类对象调用
begin + endbegin获取字符串开头的迭代器 + end获取最后一个字符下一个位置的迭代器
rbegin + rendrbegin指向字符串开始的反向迭代器 + 指向字符串反向末端的方向迭代器
范围forc++11支撑更加简洁的范围for的新遍历方式
  1 #include<iostream>
  2 #include<string>
  3 using namespace std;
  4 int main(){
  5     string str("helloc world");
  6     const string s2("helloc ybb");
  7     cout << s1 << " " << s2 << endl;
  8     cout << s1[0] << " " << s2[0] << endl;
  9     s1[0] = 'T';
 10     cout << s1 << endl;
 11     // s2[0]='t'; 代码编译失败,因为const类型对象不能修改
 12     return 0;
 13 }

在这里插入图片描述

string类的遍历方式有三种,一种就是用string重载的[]来进行下标访问,用for循环遍历。第二种就是使用迭代器来遍历。第三种,是使用范围for来遍历。

   1 #include<iostream>
  2 using namespace std;
  3 int main()
  4 {
  5 
  6     string str("hello ybb!!");
  7     // 使用重载的[],通过访问下标来遍历string
  8     for(size_t i = 0; i < str.size();++i){
  9         cout << s[i] << endl;
 10     }
 11     
 12     // 使用迭代器来遍历string
 13     string::iterator it = str.begin();
 14     while(it != str.end()){
 15         cout << *it << end;
 16         ++it;
 17     }
 18     
 19     // 使用迭代器反向遍历string
 20     string::reverse_iterator rit = str.rbegin();
 21     while(rit != str.rend())
 22     {   
 23         cout << *rit <<endl;
 24         ++rit;
 25     }
 26     
 27     //  使用范围for来遍历字符串
 28     for(auto e : s){
 29         cout << ch << endl;
 30     }
 31     return 0;
 32 }

在这里插入图片描述

4. string类对象的修改操作
函数名称功能说明
push_back在字符串后尾插字符
append在字符串后追加一个字符串
operator+=在字符串后 追加字符串
c_str返回C格式的字符串
find + npos从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
rfind从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
substr在str中从pos位置开始,截取n个字符,然后将其返回
  1 #include<iostream>
  2 using namespace std;
  3 
  4 int main(){
  5 
  6     string str("hello");
  7     str.push_back('T'); // 在str后插入一个字符T
  8     str.append(" ybb"); // 在str后追加一个字符串“ ybb”
  9     str += 'b'; // 在str后追加一个字符'b'
 10     str += " tz"; // 在str后追加一个字符串" tz"
 11     cout << str << endl;
 12     cout << str.c_str() << endl; // 以c语言的方式打印字符串
 13 
 14     // 获取file的后缀
 15     string file("test.txt");
 16     size_t pos = file.rfind('.'); // 获取'.'的位置
 17     string suffix(file.substr(pos, file.size()-pos)); // 用从pos开始,
    截取file.size() - pos 个字符的子串
 18     cout << suffix << endl;
 19 
 20     // npos是string里面的一个静态成员变量
 21     // static const size_t npos = -1;
 22 
 23 
 24     // 做一个小测试,取出url中域名
 25     string url("https://cplusplus.com/reference/string/string/");
 26     cout << url << endl;
 27     size_t start = url.find("://");
 28     if(start == string::npos)
 29     {
 30         cout << "invalid url" <<endl;
 31         return 0;
 32     }
 33 
 34     start += 3;
 35     size_t finish = url.find('/',start);
 36     
 37     string addr = url.substr(start, finish - start);
 38     
 39     cout << addr << endl;
 40     
 41     // 删除协议前缀
 42     url.erase(0, start);
 43     cout << url << endl;
 44     
 45     return 0;
 46 }   
 47 

在这里插入图片描述

注意:

  1. 在string尾部追加字符时,str.push_back('c')str.append(1,'c')str+='c'三种方式差不多,但一般情况下string类使用+=操作比较多,+=不仅可以连接单个字符,还可以连接字符串
  2. 对string操作时,如果能够大概预估到方多少字符,可以先通过reserve把空间预留好
    5 return 0;
    46 }
    47
    ``
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_yiyi_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值