String类

1、STL简介

1.1、什么是STL

是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。

1.2、STL六大组件

1、容器:string ; vector ;  list  ;deque ; map ;  set ; multimap ; mutilset

2、迭代器:  iterator ; const_iterator ; reverse_iterator ;const_reverse_iterator 

3、仿函数: greater; less....

4、算法:  find; swap; reverse ;sort ;  merge ;

5、空间配置器:  allocator

6、配接器: stack ; queue ; priority_queue

2、标准库中的string

2.1、string类的常用接口说明

1、string类对象的常见构造

string():构造空的string类对象,即空字符串

string(const char*s) :C-string来构造string类对象,常量字符串进行初始化。

        string s1("hello");

string(size_t n,char c) : string类对象中包含n个字符c

        string s2(10,'*');

string(const string&s): 拷贝构造函数

        string s3(s2);

2、string类对象的容量操作

size():返回字符串有效字符长度

length():返回字符串有效字符长度

capacity():返回空间总大小

empty():检测字符串释放为空串,是返回true,否则返回false

caear():清空有效字符

reserver():为字符串预留空间

resize():将有效字符的个数改为n个,多出的空间用字符c填充

3、访问及遍历操作

operator[ ]:返回pos位置的字符, const string 类对象调用

可以一个一个打印字符,可以遍历字符串。可以像数组一样去使用

begin+ end:获取一个字符的迭代器+end获取最后一个字符的下一个位置的迭代器

rbegin + rend:同上

范围for:C++11支持更简洁的范围for的新遍历方式

char s3 = "hello world";

s3[1];---->它的底层是-----(s3是数组名,数组名是首元素地址)。*(s3+1)

s1[1];----->它的底层是-----s1.operator[](1);

4、string类对象的修改操作

push back:在字符串后尾插字符c (一个字符)

append:在字符串之后追加一个字符串 (一个字符串)

operator+=:在字符串后追加字符串str  (一个字符串) (自己会扩容)

c str:返回c格式字符出

find+npos:从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置

rfind:从字符串pos的位置开始往前找字符c,返回该字符·在字符串中的位置

substr:在str中从pos位置开始,截取n个字符,然后将其返回

5、str类的非成员函数

operator+:尽力少用,因为传值返回,导致深拷贝效率低

operator>>:数入运算符重载

operator<<:输出运算符重载

getline:获取一行字符串

relation operators:大小比较

6、增删改查

void reserve(size_t n)  //reserve开空间不只是给push_back和append使用,外面的开空间也可以使用,因此需要对n进行判断
{
   if(n > _capacity)
    {
        char* tmp = new char[ n +1];
        strcpy(tmp,_str);
        delete[] _str;
        _str = tmp;
        _capacity = n;
    }
        
}

void push_back(char ch)
{
    if(_size == capacity)
    {
        //2倍扩容
        reserve(_capacity == 0 ? 4 : _capacity * 2);
    }
        _str[size] = ch;
        ++size;
        _str[_size] = '\0';
}

void append(const char* str)
{
    size_t len = strlen(str);
    if(_size + len > _capacity)
    {
        //至少扩容到size+len
        reserve(_size + len);
    }
        strcpy(_str + _size, str);
        _size += len;
}

6、迭代器(先进行简单了解)

string::iterator it = s1.begin(); //begin指向字符串的第一个字符
while(it != s1.end())  //end指向字符串最后一个字符的下一个字符
{
    cout << *it <<" ";  //begin返回值给it *it就是数据
    ++it; //就是让it往后移动  等于end就结束了
}
cout<<endl;


//还有一个遍历字符串的方式就是使用范围for 也被称作“语法糖”
for(auto ch : s1)  //将s1给ch 然后自动推导类型,自动判断结束 //注意:这样写只能读不能进行写,这只是单纯的赋值
{
    cout<< ch << " ";  // “读”
}
cout<<endl;
for(auto &ch : s1)//只有加&才可以进行写,因为这相当于修改的是s1的别名
{
    ch++;
    cout<< ch << " ";
}

//其实范围for的底层就是迭代器

//还有反向迭代器
string s1("hello world");
string::reverse_iterator rit = s1.rbegin(); //rbegin在字符串最后一个字符的下一个字符
while(rit != s1.rend()) //rend在第一个字符
{
    cout << *rit <<" ";
    ++rit;
}
cout<<endl;

其实,iterator是一个像指针一样的类型,有可能是指针,有可能不是指针。

//任何容器都支持迭代器,并且用法是类似的
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);

vector<int>::iterator vit = v.begin();
while (vit != v.end())
{
    cout << *vit << " ";
    ++vit;
}
cout << endl;

下标+[]其实并不是主流的方式,因为树和链表就不能使用。但是数组、链表、树 都可以使用迭代器。(iterator提供的是一种统一的方式访问和修改容器的数据,算法就可以通过迭代器去处理容器中的数据)

6.1、迭代器的使用(先简单了解)

1、std::reverse ---->逆置

//接上面的代码
reverse(v.begin(),v.end());
for(auto e : v)
{
    cout << e << " ";
}
cout <<endl;

3、string类的模拟实现

class String
{
public:
    String(const char* str = "")
    {
        if(nullptr == str)
        {
            assert(false);
            return;
        }

        _str = new char[strlen(str) + 1];
        strcpy(_str,str);
    }

    String(const String& s)
        :_str(nullptr)
    {
        String strTmp(s._str);
        swap(_str,strTmp._str);
    }
    
    String& operator=(String s)
    {
        swap(_str,s._str);
        return *this;
    }

    ~String()
    {
        if(_str)
        {
            delete[] _str;
            _str = nullptr;
        }
    }
private:
    char* _str;
};

4、扩展阅读

5、补充

1、当字符串中包含空格时,如果使用流提取运算符,会默认空格作为分隔符来提取字符串。如果使用>>来提取字符串,只会得到第一个空格之前的字符串,而剩余部分会被留在输入流中。这可能导致后续的提取操作无法获取到预期的结果。

#include <iostream>

#include <string>

using namespace std;

int main()

{

string str; cout << "Enter a string with spaces: ";

cin >> str;

cout << "You entered: " << str << endl;

return 0;

}

例如上面的代码,如果输入hello world ,str只会读到hello。而 "World" 部分会留在输入流中,而不会被赋值给 str。

为了解决这个问题,可以考虑使用 getline 函数来读取一整行,而不是使用 >> 操作符

#include <iostream>
#include <string>

using namespace std;

int main() {
    string str;
    cout << "Enter a string with spaces: ";
    getline(cin, str);
    cout << "You entered: " << str << endl;
    return 0;
}
getline 函数会读取整行,包括其中的空格,而不会将空格视为分隔符。

2、string初始化的时候不能直接将str赋值给_str,必须要开空间--------------------

_str(new char[strlen(str)+1])     

            
 

  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值