您的位置:首页 > 科技 > 能源 > 模拟string(三)详解

模拟string(三)详解

2024/11/17 15:30:28 来源:https://blog.csdn.net/2301_79178723/article/details/140428625  浏览:    关键词:模拟string(三)详解

目录

  • size_t size() const获取size大小
    • 代码
  • size_t capacity()const获取capacity
    • 代码
  • char& operator[](size_t pos)获取pos位置字符
    • 代码
  • const char& operator[](size_t pos) const获取pos位置字符(只能读取不能更改)
    • 代码
  • const char* c_str() const获取_str的地址
    • 代码
  • iterator和const iterator迭代器
    • iterator begin()和const iterator begin()
      • 代码
    • iterator end()和const iterator end()
      • 代码
  • void erase(size_t pos, size_t len = npos)从len位置开始往前删除数据到pos位置
    • 错误写法
    • 代码
  • void resize(size_t n, char ch = '\0')插入数据
    • 代码
  • size_t find(char ch)查找字符所在位置
    • 代码
  • size_t find(char ch,size_t pos=0) const查找pos位置之后字符所在的位置
    • 代码
  • size_t find(const char* sub, size_t pos = 0) const查找pos位置开始字符串所在位置
    • 代码
  • string substr(size_t pos = 0, size_t len = npos)取pos位置之后指定长度的字符串
    • 代码

感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接
🐒🐒🐒 个人主页
🥸🥸🥸 C语言
🐿️🐿️🐿️ C语言例题
🐣🐣🐣 python
🐓🐓🐓 数据结构C语言
🐔🐔🐔 C++
🐿️🐿️🐿️ 文章链接目录

size_t size() const获取size大小

因为返回的值是不允许被修改的,所以在后面加了个const

代码

size_t size() const
{return _size;
}

size_t capacity()const获取capacity

代码

size_t capacity()const
{return _capacity;
}

char& operator[](size_t pos)获取pos位置字符

这里有两个函数,因为有时候会遇到常量字符串,就是只能读取数据,但是不能修改,所以需要分两个函数来对待不同的情况

代码

char& operator[](size_t pos)
{assert(pos<_size);return _str[pos];
}

const char& operator[](size_t pos) const获取pos位置字符(只能读取不能更改)

代码

	const char operator[](size_t pos) const{assert(pos < _size);return _str[pos];}

我们加上断言可以防止访问越界,并且因为pos位置的空间是通过new开辟出来的,而new开辟出来的空间是存在堆上的,所以这里出了作用域并不会被销毁,因此我们就直接引用返回,引用返回的好处是在函数外面我们不仅可以读取数据,还可以更改数据

const char* c_str() const获取_str的地址

代码

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

iterator和const iterator迭代器

迭代器我们用指针来实现

iterator begin()和const iterator begin()

代码

typedef char* iterator;iterator begin(){return _str;}
typedef const char* iterator const;const iterator begin() const{return _str;}

我们将char*类型简化命名为iterator,由于是在类域里面,所以不会和string中的iterator冲突

iterator end()和const iterator end()

代码

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

void erase(size_t pos, size_t len = npos)从len位置开始往前删除数据到pos位置

错误写法

	static const size_t npos = -1;void erase(size_t pos, size_t len = npos){assert(pos <= _size);if (len == npos || len+pos >= _size ){_str[pos] = '\0';_size = pos;}else{strcpy(_str + pos, _str + pos + len);_size -= len;}}

但是这里有溢出的风险,pos+len中如果pos=npos,因为npos已经是最大值了,npos+一个任意数就溢出了,所以需要对这里进行一点修改

static const size_t npos = -1;
void erase(size_t pos, size_t len = npos)
{assert(pos <= _size);if (len == npos || len >= _size - pos){_str[pos] = '\0';_size = pos;}else{strcpy(_str + pos, _str + pos + len);_size -= len;}
}

_size-pos的最大值也是npos,但是strcpy(_str + pos, _str + pos + len)也有_str + pos + len,这不还是有溢出的风险吗,所以我觉得可以直接加个断言这样要方便很多

代码

	static const size_t npos = -1;
void erase(size_t pos, size_t len = npos)
{assert(pos <= _size);assert(_size + pos + len <= npos);if (len == npos || len >= _size - pos){_str[pos] = '\0';_size = pos;}else{strcpy(_str + pos, _str + pos + len);_size -= len;}
}

static const size_t npos = -1是因为我写的函数用了命名空间域包起来的,直接用npos会显示未定义,所以我就自己定义了一个npos

void resize(size_t n, char ch = ‘\0’)插入数据

代码

void resize(size_t n, char ch = '\0')
{if (n <= _size){_str[n] = '\0';_size = n;}else{reserve(n);for (size_t i = _size; i < n; i++){_str[i] = ch;}_str[n]='\0';_size = n;}
}

代码逻辑为当n小于等于size的时候就以n位置为结束位置,让_str[n]=’\0’,不管后面是否还有数据,总之就是n后面的数据不要了

当n大于_size的时候,就从_size位置开始尾差字符ch

size_t find(char ch)查找字符所在位置

代码

size_t find(char ch)
{for (size_t i = 0; i < _size; i++){if (_str[i] == ch){return i;}}return npos;
}

这个比较容易理解,就是遍历一遍字符串,找到字符ch就返回下标
没有找到就返回npos,因为npos是最大的值,一般的字符串都没有那么大,所以返回npos就表示没有找到

size_t find(char ch,size_t pos=0) const查找pos位置之后字符所在的位置

代码

size_t find(char ch,size_t pos=0) const
{for (size_t i = pos; i < _size; i++){if (_str[i] == ch){return i;}}return npos;
}

和上面的完全一样,区别就是是从pos位置开始遍历,而上面的是从最开始的位置遍历

size_t find(const char* sub, size_t pos = 0) const查找pos位置开始字符串所在位置

代码

size_t find(const char* sub, size_t pos = 0) const
{assert(pos < _size);const char* p = strstr(_str+pos, sub);if (p){return p - _str;}elsereturn npos;
}

这个是直接用 strstr去找的,strstr作用是返回字符串中首次出现子串的地址。
如果strstr返回的不是空,就说明找到了,所以返回下标就是两个指针相减,没找到就返回npos

string substr(size_t pos = 0, size_t len = npos)取pos位置之后指定长度的字符串

代码

	string substr(size_t pos = 0, size_t len = npos){string sub;if (len == npos || len >= _size - pos){for (size_t i = pos; i < _size; i++){sub += _str[i];}}else{for (size_t i = pos; i < pos+len; i++){sub += _str[i];}}return sub;}

有两种情况如下图:
pos+len<size

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fmxCytoz-1721783392372)(https://i-blog.csdnimg.cn/direct/ea108802adc345ae8bcc4e37c50c1e9e.png)]
pos+len>=size
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UTZtPmmP-1721783392375)(https://i-blog.csdnimg.cn/direct/520fc2c971ad4b9da282e066f7eed7ab.png)]
我们要去len个长度的字符串,第一中情况就可以直接取,因为len+pos小于size,所以不用担心在取的时候越界
第二种情况就是len+pos>=size,这个时候就要注意不能取越界了,所以就从pos位置一直取到size位置

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com