#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<assert.h>
namespace yuren {
class string
// 管理字符串的数组,可以增删查改
// 字符串数组的结尾有\0
// 支持增删查改
{
public:
typedef char* iterator;
typedef const char* const_iterator; //为后续遍历string时使用。
iterator begin()
{
return _str;
}
const_iterator begin()const
{
return _str;
}
iterator end()
{
return _str + _size;
}
const_iterator end() const
{
return _str + _size;
}
void swap(string& s)
{
std::swap(_str, s._str);
std::swap(_size, s._size);
std::swap(_capacity, s._capacity);
}
string(const char* str = "") //构造函数
{
_size = strlen(str);
_capacity = _size;
_str = new char[_capacity + 1];//给'\0'留出位置
strcpy(_str, str);
}
string(const string& s) //拷贝构造
:_capacity(0)
, _size(0)
, _str(nullptr)
{
string tmp(s._str);
swap(tmp);
}
string& operator=(string s) //赋值构造
{
swap(s);
return *this;
}
~string() //析构函数
{
delete[]_str;
_size = _capacity = 0;
}
// 遍历 []需要写两个 读跟写
// at 作用和operator[]类似,越界抛异常
//读
const char& operator[](size_t n)const
{
return _str[n];
}
//可读可写
char& operator[](size_t n)
{
return _str[n];
}
//写字符 写字符串
void pushback(const char& val) //加入单个字符
{
//第一步检查空间是否足够
if (_size == _capacity)
{
//先开辟空间
int newcapacity = _capacity == 0 ? 4 : 2 * _capacity;
char* tmp = new char[newcapacity + 1];
if (tmp == nullptr)
{
std::cout << "开辟失败" << std::endl;
exit(-1);
}
strcpy(tmp, _str);
delete[]_str;
_str = tmp;
_capacity = newcapacity;
}
_str[_size] = val;
_str[_size + 1] = '\0';
_size += 1;
}
void reserve(size_t n)
{
if (n > _capacity)
{
char* tmp = new char[n + 1];//开辟n+1个大小的空间 加1的目的是为了后序遍历遇到'\0';
if (tmp == nullptr)
{
std::cout << "开辟失败" << std::endl;
exit(-1);
}
strncpy(tmp, _str, _size + 1);
delete[]_str;
_str = tmp;
_capacity = n;
}
}
size_t size()
{
return _size;
}
size_t capacity()
{
return _capacity;
}
void append(const char* val) //这里就是pushback一个字符串
{
//第一步计算要oushback字符串的长度
size_t n = strlen(val);
//查看现有空间是否足够 如果不够开辟
if (_size + n > _capacity)
{
//这里的开辟我们可以直接写成一个函数方便后续的调用 reserve
reserve(_size + n);
}
//while 循环插入
size_t v = size();
while (*val != '\0')
{
_str[v] = *val;
val++;
}
_str[_size + n] = '\0';
}
//运算符重载+=
string& operator+=(const char& val) //分两个一个是加字符 另一个是加一段字符串
{
if (_size + 1 > _capacity)
{
reserve(_size + 1);
}
_str[_size] = val;
_str[_size + 1] = '\0';
return *this;
}
string& operator+=(const char* ch)
{
append(ch);
return *this;
}
string& insert(size_t pos, char chh) //在某个位置处插入一个字符
{
assert(pos <= size());
//检查空间
if (_size + 1 > _capacity)
{
reserve(_size + 1);
}
//移动数据
char* ch = _str + pos;
char* end = _str + _size;
while (end >= ch)
{
*(end + 1) = *end;
end--;
}
_str[pos] = chh;
_size++;
return *this;
}
string& insert(size_t pos, const char* chh)
{
//插入一段字符串
//先计算要插入的长度大小
size_t len = strlen(chh);
//检查空间是否足够 如果不够就要开空间
if (len + _size > _capacity)
{
reserve(len + _size);
}
//开辟完成后插入数据
char* begin = _str + pos;
char* end = _str + _size;
while (end >= begin)
{
*(end + len) = *end;
end--;
}
//pos处的空间空出来了 接着插入这段字符串
strncpy(_str, chh, len);
_size += len;
return *this;
}
string& erase(size_t pos, size_t len = npos) //删除某一位置上长度为len的数据
{
assert(pos < _size);
size_t leftLen = _size - pos;
// 1、剩余的字符长度小于要删的长度 (后面全部删完)
// 2、剩余的字符长度大于要删的长度 判断是否要移动数据
if (len >= leftLen)
{
_str[pos] = '\0';
_size = pos;
}
else
{
strcpy(_str + pos, _str + pos + len);
_size -= len;
}
return*this;
}
size_t find(char ch, size_t pos = 0)
{
//从某一位置处查找字符ch
assert(pos < _size);
//遍历_str;找到该字符 然后是其他字符前移动就可
char* begin = _str + pos;
char* end = _str + _size;
while (begin < end)
{
if (*begin == ch)
{
return begin - _str;
}
begin++;
}
return npos;
}
size_t find(char* ch, size_t pos = 0)
{
//从pos处开始 找一段字符串
assert(pos < _size);
char* ret = strstr(_str + pos, ch);
if (ret)
{
return ret - _str;
}
else
{
return npos;
}
}
void clear()
{
_size = 0;
_str[0] = '\0';
}
const char* c_str() const
{
return _str;
}
private:
size_t _size;
size_t _capacity;
char* _str;
static const size_t npos;
};
const size_t string::npos = -1;
inline bool operator<(const string& s1, const string& s2)
{
return strcmp(s1.c_str(), s2.c_str()) < 0;
}
inline bool operator==(const string& s1, const string& s2)
{
return strcmp(s1.c_str(), s2.c_str()) == 0;
}
inline bool operator<=(const string& s1, const string& s2)
{
return s1 < s2 || s1 == s2;
}
inline bool operator>(const string& s1, const string& s2)
{
return !(s1 <= s2);
}
inline bool operator>=(const string& s1, const string& s2)
{
return !(s1 < s2);
}
inline bool operator!=(const string& s1, const string& s2)
{
return !(s1 == s2);
}
std::ostream& operator<<(std::ostream& cout, const string& s)
{
for (auto ch : s)
{
cout << ch;
}
return cout;
}
std::istream& operator>>(std::istream& in, string& s)
{
s.clear();
char ch;
ch = in.get();
while (ch != ' ' && ch != '\n')
{
s += ch;
ch = in.get();
}
return in;
}
}
#include"string.h"
using namespace yuren;
int main()
{
string s1("hello");
string s2("world");
string s3 = s2;
s1 += "world";
std::cout << s1;
s1 +='w';
s1.pushback('c');
s1.append("ao");
s1.erase(0, 1);
s1.find('c');
s1.insert(2,"aoo");
s1.erase(2, 3);
return 0;
}
c++string函数实现 已经加入注释解释 求赞
最新推荐文章于 2024-06-14 11:15:55 发布