[C++]:5.STL:string(2)

C++:5.STL:string 2

前言

今天就是String的第二节课啦,我们这节课要讲String类的实现,因为比较简单,所以我们以代码为主 (其实主要原因是博主忙着刷题 )。这里主要讲一些常用的String类的方法,博主基本都实现了一下。下面让我们开始吧!首先就是本章的思维导图了!见下图>>

四个默认成员函数

构造函数

cpp 复制代码
string(const char* s = "")
    :_str(new char[strlen(s)+1])
    ,_size(0)
    ,_capacity(strlen(s))
{
    strcpy(_str, s);
    _size = _capacity;
}

析构函数

cpp 复制代码
~string()
{
    delete[] _str;
    _str = nullptr;
    _capacity = _size = 0;
}

拷贝构造函数

cpp 复制代码
string(const string& str)
    :_str(new char[strlen(str._str)+1])
    ,_size(0)
    ,_capacity(strlen(str._str))
{
    strcpy(_str, str._str);
    _size=_capacity;
}

赋值操作符重载函数

cpp 复制代码
string& operator=(const string& str)
{
    if (str._size > _capacity)
    {
        size_t newcapacity = str._size * 2;
        reserve(newcapacity);
    }
    strcpy(_str, str._str);
    _size = str._size;

    return *this;
}

string& operator=(const char* s)
{
    size_t size = strlen(s);
    if (size > _capacity)
    {
        size_t newcapacity = size * 2;
        reserve(newcapacity);
    }
    strcpy(_str, s);
    _size = size;

    return *this;
}

修改器

插入元素

cpp 复制代码
void push_back(char c)
{
    if (_size == _capacity)
    {
        size_t newcapacity = (_size + 1) * 2;
        reserve(newcapacity);
    }
    _str[_size] = c;
    ++_size;
    _str[_size] = '\0';
}

void append(const char* s)
{
    size_t size = strlen(s);
    if (_size + size > _capacity)
    {
        size_t newcapacity = (_size + size) * 2;
        reserve(newcapacity);
    }
    strcpy(_str + _size, s);
    _size += size;
}
string& operator+=(char c)
{
    push_back(c);

    return *this;
}

string& operator+=(const char* s)
{
    append(s);

    return *this;
}

获取c风格字符串的首元素地址

cpp 复制代码
const char* c_str()const
{
    return _str;
}

清除元素

cpp 复制代码
void clear()
{
    _size = 0;
    _str[0] = '\0';
}

交换类对象的值

cpp 复制代码
void swap(string& str)
{
    string tmp = str;
    str = *this;
    *this = tmp;
}

空间

获取类对象的属性

获取对象元素个数

cpp 复制代码
size_t size()const
{
    return _size;
}

获取对象空间大小

cpp 复制代码
size_t capacity()const
{
    return _capacity;
}

判空

cpp 复制代码
bool empty()const
{
    return _size == 0;
}

修改元素个数

cpp 复制代码
void resize(size_t n, char c = '\0')
{
    if (n > _capacity)
    {
        size_t newcapacity = n * 2;
        reserve(newcapacity);
    }
    if (n <= _size)
    {
        _size = n;
    }
    else
    {
        for (size_t i = _size; i <= n - 1; ++i)
        {
            _str[i] = c;
        }
    }

}

扩容

cpp 复制代码
void reserve(size_t n)
{
    //申请的空间比现有的空间更大才扩容、
    if (n > _capacity)
    {
        char* tmp = new char[n + 1];//实际空间为有效空间+1,因为要放'\0'
        strcpy(tmp, _str);
        delete[] _str;
        _str = tmp;
        _capacity = n;
    }
}

访问

用 访问

cpp 复制代码
char& operator[](size_t index)
{
    return _str[index];
}

const char& operator[](size_t index)const
{
    return _str[index];
}

相关的操作符

比较对象

cpp 复制代码
//因为oprator<等要调用compare(),所以这里实现一下
size_t compare(const string& str)const
{
    size_t size = _size < str._size ? _size : str._size;
    for (size_t i = 0; i < size; ++i)
    {
        if (_str[i] < str._str[i])
        {
            return -1;
        }
        else if(_str[i] > str._str[i])
        {
            return 1;
        }
    }
    //一方比较完,并在该区间内两方所有字符都相等
    return _size - str._size;
}

大于

cpp 复制代码
bool operator>(const string& str)
{
    return compare(str) > 0;
}

等于

cpp 复制代码
bool operator==(const string& str)
{
    return compare(str) == 0;
}

小于

cpp 复制代码
bool operator<(const string& str)
{
    return compare(str) < 0;
}

大于或等于

cpp 复制代码
bool operator>=(const string& str)
{
    return compare(str) >= 0;
}

小于或等于

cpp 复制代码
bool operator<=(const string& str)
{
    return compare(str) <= 0;
}

不等于

cpp 复制代码
bool operator!=(const string& str)
{
    return compare(str) != 0;
}

其他方法

查找元素

cpp 复制代码
// 返回c在string中第一次出现的位置
size_t find(char c, size_t pos = 0) const
{
    for (size_t i = pos; i < _size; ++i)
    {
        if (_str[i] == c)
        {
            return i;
        }
    }
    return npos;
}

// 返回子串str在string中第一次出现的位置
size_t find(const char* s, size_t pos = 0) const
{
    size_t size = strlen(s);
    if (( size> _size-pos) ||(pos>=_size))
    {
        return npos;
    }
    
    size_t index = 0;
    size_t previ = 0;
    for (size_t i = pos; i < _size; ++i)
    {
        if (_str[i] != s[index])
        {
            if (index > 0)
            {
                i = previ;
            }
            index = 0;
        }
        else
        {
            if (index == 0)
            {
                previ = i;//记录上一次匹配时i的位置
            }
            ++index;
            if (index == size)
            {
                break;
            }
        }
    }
    if (index == size)
    {
        return previ;
    }
    else
    {
        return npos;
    }
}

插入元素

cpp 复制代码
// 在pos位置上插入字符c/字符串str,并返回该字符的位置

string& insert(size_t pos, char c)
{
    //pos在_str有效范围内才插入
    if (pos < _size)
    {
        if (_size == _capacity)
        {
            size_t newcapacity = (_size + 1) * 2;
            reserve(newcapacity);
        }
        //'\0'也要往后移动
        for (size_t i = _size; i >= pos; --i)
        {
            _str[i + 1] = _str[i];
        }
        _str[pos] = c;
        _size += 1;
    }

    return *this;
}

string& insert(size_t pos, const char* s)
{
    //pos在_str有效范围内才插入
    if (pos < _size)
    {
        size_t size = strlen(s);
        if (size + _size > _capacity)
        {
            size_t newcapacity = (size + _size) * 2;
            reserve(newcapacity);
        }
        for (size_t i = _size; i >= pos; --i)
        {
            _str[i + size] = _str[i];
        }
        for (size_t i = pos; i < pos + size; ++i)
        {
            _str[i] = s[i - pos];
        }
        _size += size;

    }

    return *this;
}

删除元素

cpp 复制代码
// 删除pos位置上的元素,并返回该元素的下一个位置
string& erase(size_t pos, size_t len)
{
    //pos位置存在才删除元素
    if (pos < _size)
    {
        //保证len合法
        if (len > _size - pos)
        {
            len = _size - pos;
        }

        for (size_t i = pos+len; i <= _size; ++i)
        {
            _str[i - len] = _str[i];
        }
        _size -= len;
    }
    return *this;
}

流插入操作符重载

cpp 复制代码
ostream& firdawn::operator<<(ostream& _cout, const firdawn::string& str)
{
	firdawn::string::iterator it = str.begin();
	while (it != str.end())
	{
		_cout << *it;
		++it;
	}

	return _cout;
}

流提取操作符重载

cpp 复制代码
istream& firdawn::operator>>(istream& _cin, firdawn::string& str)
{
	str = "";
	char c = '\0';
	while ((c = _cin.get()) != EOF)
	{
		if (c == ' ' || c == '\n')
		{
			break;
		}
		else
		{
			str += c;
		}
	}

	return _cin;
}

获取一整行的元素

cpp 复制代码
void firdawn::getline(istream& _cin, firdawn::string& str)
{
	str = "";
	char c = '\0';
	while ((c = _cin.get()) != EOF)
	{
		if (c == '\n')
		{
			break;
		}
		else
		{
			str += c;
		}
	}
}

全部代码

String.h

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>
#include<cassert>
using namespace std;


namespace firdawn
{

    class string
    {
    public:
        typedef char* iterator;
        const static size_t npos;

        //四个默认成员函数
        string(const char* s = "")
            :_str(new char[strlen(s)+1])
            ,_size(0)
            ,_capacity(strlen(s))
        {
            strcpy(_str, s);
            _size = _capacity;
        }

        string(const string& str)
            :_str(new char[strlen(str._str)+1])
            ,_size(0)
            ,_capacity(strlen(str._str))
        {
            strcpy(_str, str._str);
            _size=_capacity;
        }

        string& operator=(const string& str)
        {
            if (str._size > _capacity)
            {
                size_t newcapacity = str._size * 2;
                reserve(newcapacity);
            }
            strcpy(_str, str._str);
            _size = str._size;

            return *this;
        }

        string& operator=(const char* s)
        {
            size_t size = strlen(s);
            if (size > _capacity)
            {
                size_t newcapacity = size * 2;
                reserve(newcapacity);
            }
            strcpy(_str, s);
            _size = size;

            return *this;
        }

        ~string()
        {
            delete[] _str;
            _str = nullptr;
            _capacity = _size = 0;
        }



            //////////////////////////////////////////////////////////////

            // iterator

        const iterator begin()const
        {
            return _str;
        }

        const iterator end()const
        {
            return _str + _size;
        }



            /////////////////////////////////////////////////////////////

            // modify

        void push_back(char c)
        {
            if (_size == _capacity)
            {
                size_t newcapacity = (_size + 1) * 2;
                reserve(newcapacity);
            }
            _str[_size] = c;
            ++_size;
            _str[_size] = '\0';
        }

        void append(const char* s)
        {
            size_t size = strlen(s);
            if (_size + size > _capacity)
            {
                size_t newcapacity = (_size + size) * 2;
                reserve(newcapacity);
            }
            strcpy(_str + _size, s);
            _size += size;
        }
        string& operator+=(char c)
        {
            push_back(c);

            return *this;
        }

        string& operator+=(const char* s)
        {
            append(s);

            return *this;
        }

        void clear()
        {
            _size = 0;
            _str[0] = '\0';
        }

        void swap(string& str)
        {
            string tmp = str;
            str = *this;
            *this = tmp;
        }

        const char* c_str()const
        {
            return _str;
        }



        /////////////////////////////////////////////////////////////

        // capacity

        size_t size()const
        {
            return _size;
        }

        size_t capacity()const
        {
            return _capacity;
        }

        bool empty()const
        {
            return _size == 0;
        }

        void resize(size_t n, char c = '\0')
        {
            if (n > _capacity)
            {
                size_t newcapacity = n * 2;
                reserve(newcapacity);
            }
            if (n <= _size)
            {
                _size = n;
            }
            else
            {
                for (size_t i = _size; i <= n - 1; ++i)
                {
                    _str[i] = c;
                }
            }

        }

        void reserve(size_t n)
        {
            //申请的空间比现有的空间更大才扩容、
            if (n > _capacity)
            {
                char* tmp = new char[n + 1];//实际空间为有效空间+1,因为要放'\0'
                strcpy(tmp, _str);
                delete[] _str;
                _str = tmp;
                _capacity = n;
            }
        }



        /////////////////////////////////////////////////////////////

        // access

        char& operator[](size_t index)
        {
            return _str[index];
        }

        const char& operator[](size_t index)const
        {
            return _str[index];
        }


        /////////////////////////////////////////////////////////////

        //relational operators

        //因为oprator<等要调用compare(),所以这里实现一下
        size_t compare(const string& str)const
        {
            size_t size = _size < str._size ? _size : str._size;
            for (size_t i = 0; i < size; ++i)
            {
                if (_str[i] < str._str[i])
                {
                    return -1;
                }
                else if(_str[i] > str._str[i])
                {
                    return 1;
                }
            }
            //一方比较完,并在该区间内两方所有字符都相等
            return _size - str._size;
        }

        bool operator<(const string& str)
        {
            return compare(str) < 0;
        }

        bool operator<=(const string& str)
        {
            return compare(str) <= 0;
        }

        bool operator>(const string& str)
        {
            return compare(str) > 0;
        }

        bool operator>=(const string& str)
        {
            return compare(str) >= 0;
        }

        bool operator==(const string& str)
        {
            return compare(str) == 0;
        }

        bool operator!=(const string& str)
        {
            return compare(str) != 0;
        }



        // 返回c在string中第一次出现的位置
        size_t find(char c, size_t pos = 0) const
        {
            for (size_t i = pos; i < _size; ++i)
            {
                if (_str[i] == c)
                {
                    return i;
                }
            }
            return npos;
        }

        // 返回子串str在string中第一次出现的位置
        size_t find(const char* s, size_t pos = 0) const
        {
            size_t size = strlen(s);
            if (( size> _size-pos) ||(pos>=_size))
            {
                return npos;
            }
            
            size_t index = 0;
            size_t previ = 0;
            for (size_t i = pos; i < _size; ++i)
            {
                if (_str[i] != s[index])
                {
                    if (index > 0)
                    {
                        i = previ;
                    }
                    index = 0;
                }
                else
                {
                    if (index == 0)
                    {
                        previ = i;//记录上一次匹配时i的位置
                    }
                    ++index;
                    if (index == size)
                    {
                        break;
                    }
                }
            }
            if (index == size)
            {
                return previ;
            }
            else
            {
                return npos;
            }
        }

        // 在pos位置上插入字符c/字符串str,并返回该字符的位置

        string& insert(size_t pos, char c)
        {
            //pos在_str有效范围内才插入
            if (pos < _size)
            {
                if (_size == _capacity)
                {
                    size_t newcapacity = (_size + 1) * 2;
                    reserve(newcapacity);
                }
                //'\0'也要往后移动
                for (size_t i = _size; i >= pos; --i)
                {
                    _str[i + 1] = _str[i];
                }
                _str[pos] = c;
                _size += 1;
            }

            return *this;
        }

        string& insert(size_t pos, const char* s)
        {
            //pos在_str有效范围内才插入
            if (pos < _size)
            {
                size_t size = strlen(s);
                if (size + _size > _capacity)
                {
                    size_t newcapacity = (size + _size) * 2;
                    reserve(newcapacity);
                }
                for (size_t i = _size; i >= pos; --i)
                {
                    _str[i + size] = _str[i];
                }
                for (size_t i = pos; i < pos + size; ++i)
                {
                    _str[i] = s[i - pos];
                }
                _size += size;

            }

            return *this;
        }



        // 删除pos位置上的元素,并返回该元素的下一个位置
        string& erase(size_t pos, size_t len)
        {
            //pos位置存在才删除元素
            if (pos < _size)
            {
                //保证len合法
                if (len > _size - pos)
                {
                    len = _size - pos;
                }

                for (size_t i = pos+len; i <= _size; ++i)
                {
                    _str[i - len] = _str[i];
                }
                _size -= len;
            }
            return *this;
        }

    private:
        char* _str;
        size_t _size;//有效元素个数
        size_t _capacity;//能够存放的有效元素个数
    };


    ostream& operator<<(ostream& _cout, const string& str);
    istream& operator>>(istream& _cin, string& str);
    void getline(istream& _cin, firdawn::string& str);

}

String.cpp

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1

#include "String.h"

const size_t firdawn::string::npos = -1;

ostream& firdawn::operator<<(ostream& _cout, const firdawn::string& str)
{
	firdawn::string::iterator it = str.begin();
	while (it != str.end())
	{
		_cout << *it;
		++it;
	}

	return _cout;
}
istream& firdawn::operator>>(istream& _cin, firdawn::string& str)
{
	str = "";
	char c = '\0';
	while ((c = _cin.get()) != EOF)
	{
		if (c == ' ' || c == '\n')
		{
			break;
		}
		else
		{
			str += c;
		}
	}

	return _cin;
}

void firdawn::getline(istream& _cin, firdawn::string& str)
{
	str = "";
	char c = '\0';
	while ((c = _cin.get()) != EOF)
	{
		if (c == '\n')
		{
			break;
		}
		else
		{
			str += c;
		}
	}
}

Test.cpp

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1

#include"String.h"


void TestString1()
{
	firdawn::string str;
	firdawn::string str2("Time and Tide wait for no man");
	firdawn::string str3 = str2;
	firdawn::string str4;
	str4 = str2;
	str.resize(10);
	size_t find= str3.find("and ");
	cout << str2 << endl;
	cout << str3.c_str() << endl;
	for (size_t i = 0; i < str4.size(); ++i)
	{
		cout << str4[i] << " ";
	}
	cout << endl;

	str = str2;
	for (auto c : str)
	{
		cout << c << " ";
	}
	cout << endl;
	str.clear();
	cout << str << endl;

	/*str = str2;
	str += "Trust youself";
	cout << str << endl;
	cin >> str;
	cout << str << endl;
	firdawn::getline(cin, str);
	cout << str << endl;*/

	str = str2;
	str.insert(find, "and girl ");
	cout << str << endl;
	str.erase(find, strlen("and girl "));
	cout << str << endl;

	str.erase(find, strlen("and tide "));
	cout << str << endl;

	cout << str << endl;
	cout << str2 << endl;
	bool less = str > str2;
	bool lessOrEqual = str != str2;
	cout << less << endl;
	cout << lessOrEqual << endl;

	str.insert(find, "and tide");
	cout << str << endl;

}

int main()
{
	TestString1();

	return 0;
}
相关推荐
hhhjhl1 小时前
Undici 跨端三方库仓颉适配全流程
java·开发语言·ubuntu
wangchunyu1141 小时前
JAVA JVM内存结构与运行时数据区
java·开发语言·jvm
光锥智能2 小时前
海康机器人举行2026移动机器人新品发布会:箱式存拣升级,「明智」系列发布
java·前端·机器人
行思理2 小时前
Nginx 跨站请求(CORS)配置完全指南:从原理到生产实践
java·前端·nginx
小溪学编程2 小时前
Spring @Bean 与 @Component 注解的区别详解
java·后端·spring
Wang's Blog3 小时前
Java 项目实战: 交友项目 - 圈子互动章总结与自检清单
java·bootstrap·交友
xyouyuweizhu3 小时前
字节流与字符流:Java IO 的两条主线该怎么选
java·开发语言·python
代码方舟3 小时前
零信任架构实战:基于天远人企关联构建自动化供应链核心企业关联穿透与利益冲突审查网关
java·人工智能·架构·自动化
小超人诞生日记4 小时前
C++ 异常机制详解:从抛出捕获到异常安全
c++·算法