博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
string类——C++
阅读量:3945 次
发布时间:2019-05-24

本文共 4690 字,大约阅读时间需要 15 分钟。

string类

  1. string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator> string;
  2. 在使用string类时,必须包含#include头文件以及using namespace std;

string常见接口

string的其中一个缺点是,插入数据,空间不够需要增容,增容是有性能消耗。

常见构造

  • string()
    • 构造空的string类对象,即空字符串
  • string(const char s)*
    • 用C-string(c格式的字符串)来构造string类对象
  • string(size_t n,char c)
    • string类对象中包含n个字符c
  • string(const string& s)
    • 拷贝构造函数
#include 
#include
using namespace std;int main(){
string s1;//空字符串 string s2("helloworld"); string s3(5, 'c'); string s4(s2);//拷贝构造 cout << s1 << endl; cout << s2 << endl; cout << s3 << endl; cout << s4 << endl;}

容量操作

  • size_type size()

  • 返回字符串中现在拥有的字符数,不计算’\0’

  • size_type length()

    • 返回字符串的长度和size()返回的数字相同

size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()

  • size_type capacity()

    • 返回在重新申请更多的空间前字符串可以容纳的字符数

    一般是按照1.5倍增容,返回的总空间大小不包括‘\0’所占空间

  • bool empty()

    • 如果字符串为空则empty()返回真(true),否则返回假(false).
  • clear

    • 清空有效字符

    clear()只是将string中有效字符清空,不改变底层空间大小

  • void reserve(size_type n=0)

    • 为字符串预留空间,知道最多需要多少空间的情况下,可以省区增容的开销
  • 为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。

  • resize

    • 将有效字符的个数改成n个,多出的空间用字符c填充

    resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。

#include 
#include
using namespace std;int main(){
string s1("hello world"); string s2(""); //size() cout << s1.size() << endl;//11 cout << s2.size() << endl;//0 //length() cout << s1.length() << endl;//11 cout << s2.length() << endl;//0 //capacity() cout << s1.capacity() << endl;//15 cout << s2.capacity() << endl;//15 //reserve() s2.reserve(100); cout << s2.capacity() << endl;//111 //resize() s1.resize(20, 'x'); for (auto s1 : s1) {
cout << s1;//hello worldxxxxxxxxx } cout << endl; s1.resize(5); for (auto s1 : s1) {
cout << s1;//hello } //clear()清空 s1.clear(); cout << s1 << endl; return 0;}

访问遍历

  • operator[ ]
    • 返回pos位置的字符,const string类对象调用
  • begin+ end
    • begin获取第一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器
  • rbegin + rend
    • rbegin获取指向字符串的最后一个字符的反向迭代器 + rend获取指向字符串的第一个字符之前的理论元素
  • 范围for
    • C++11支持更简洁的范围for的新遍历方式
#include 
#include
using namespace std;int main(){
//转换成整形 string s("12345"); int value = 0; //1、size+[] for (size_t i = 0; i < s.size(); i++) {
value *= 10; value += (s[i] - '0'); } cout << value << endl; value = 0; //2、迭代器 string::iterator it = s.begin(); while (it != s.end()) {
value *= 10; value += (*it - '0'); it++; } cout << value << endl; value = 0; //反向迭代器 string::reverse_iterator rit = s.rbegin(); while (rit != s.rend()) {
value *= 10; value += (*rit - '0'); rit++; } cout << value << endl; //范围for(C++11) for (auto ch : s) {
cout << ch; }}

修改操作

  • push_back
    • 在字符串后尾插字符c
  • append
    • 在字符串后追加一个字符串
  • operator+=
    • 在字符串后追加字符或字符串
  • c_str
    • 返回C格式字符串
  • find + npos
    • 从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
  • rfind
    • 从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
  • substr
    • 在str中从pos位置开始,截取n个字符,然后将其返回
  • insert
    • 在pos位置插入字符或字符串
  • erase
    • 清除字符或字符串
#include 
#include
using namespace std;int main(){
string s("hello world"); //push_back 尾插字符 s.push_back('!'); cout << s << endl;//hello world! //append 尾插字符串 s.append("C++"); cout << s << endl;//hello world!C++ //operator+= string s1("hello"); string s2("world"); s1 += ' '; s1 += s2; cout << s1 << endl;//hello world //c_str cout << s1.c_str() << endl;//hello world //find size_t pos = s1.find(' '); cout << pos << endl;//5 //rfind size_t rpos = s1.rfind(' '); cout << rpos << endl;//5 //substr 从pos位置开始阶段 cout << s1.substr(pos) << endl;// world //insert cout << s1.insert(pos, " C++") << endl;//hello C++ world //erase 清除 s1.erase(pos, 4); cout << s1 << endl;//hello world return 0;}

string模拟实现

namespace mystring{
class string {
public: //构造函数,全缺省 string(char* str = "") :_str(new char[strlen(str) + 1]) {
strcpy(_str, str); } //析构函数 ~string() {
delete[] _str; _str = nullptr; } //拷贝构造函数,深拷贝 string(const string& s) :_str(new char[strlen(s._str)+1]) {
strcpy(_str, s._str); } //size() size_t size() {
return strlen(_str); } //operator= 赋值运算符重载 string& operator=(const string& s) {
//防止自己给自己赋值 if (this != &s) {
//开辟同样大小的空间 char* tmp = new char[strlen(s._str) + 1]; //将内容拷贝过去 strcpy(tmp, s._str); //释放原来的空间 delete[] _str; //将新的内容赋值过去 _str = tmp; } return *this; } //operator[] 运算符重载 char& operator[](size_t i) {
return _str[i]; } //c_str() const char* c_str() {
return _str; } private: //指针 char* _str; };}

转载地址:http://fbowi.baihongyu.com/

你可能感兴趣的文章
restore factory属性的enable和disable
查看>>
Android LOG机制流程图
查看>>
如何在JNI中抛异常
查看>>
Android应用程序的完全退出
查看>>
Task和Activity相关的一些属性
查看>>
JAVA系统属性之user.home
查看>>
Android代码截屏
查看>>
Android中打印代码的调用层次
查看>>
成功者十三个价值连城的习惯
查看>>
特别成功的人会做6件事
查看>>
Android: 用jni 获取MAC地址
查看>>
字符串列表的C语言实现:c_strlist
查看>>
客户沟通的方式:礼貌待客沟通方式,技巧推广沟通方式,个性服务沟通方式
查看>>
用弹性工作制留住员工
查看>>
知识=经验×反思2
查看>>
领导者如何发现关键问题
查看>>
学习无为领导力
查看>>
卓越领导看过程
查看>>
领导力与各种循环挑战
查看>>
达成谈判协议 - 避免操之过急
查看>>