当前位置: 首页 > news >正文

09 string的实现

注意

实现仿cplus官网的的string类,对部分主要功能实现

实现

头文件

#pragma once
#include <iostream>
#include <assert.h>
#include <string>namespace mystring
{class string{friend std::ostream& operator<<(std::ostream& os, const string& str);public://迭代器typedef char* iterator;typedef const char* cosnt_iterator;iterator begin(){return _str;}iterator end(){return _str + _size;}cosnt_iterator begin() const{return _str;}cosnt_iterator end() const{return _str + _size;}//初始化string(const char* str = "");string(const string& obj);string& operator=(const string& obj);//增void PsuhBack(char ch);string& Append(const char* str);string& Insert(size_t pos, char ch);string& Insert(size_t pos, const char* str);string& operator+=(char ch);string& operator+=(const char* str);void Reserve(size_t capacity);void Resize(size_t capacity, char ch = '\0');//删string& Erase(size_t pos, size_t n = npos);void Clear();//查size_t Find(char ch, size_t pos = 0);size_t Find(char* str, size_t pos = 0);const char* c_str() const{return _str;}size_t size() const{return _size;}size_t capacity() const{return _capacity;}//改char& operator[](size_t pos){assert(pos < _size);return _str[pos];}const char& operator[](size_t pos) const{assert(pos < _size);return _str[pos];}void Swap(string& obj);//不修改成员变量的,最好const//比较bool operator>(const string& s) const{return strcmp(_str, s._str) > 0;}bool operator==(const string& s) const{return strcmp(_str, s._str) == 0;}bool operator<(const string& s) const{return strcmp(_str, s._str) < 0;}bool operator>=(const string& s) const{return *this > s || s == *this;}bool operator<=(const string& s) const{return *this < s || *this == s;}bool operator!=(const string& s) const{return !(*this == s);}//析构~string(){delete[] _str;_str = nullptr;_size = _capacity = 0;}private:char* _str;size_t _size;size_t _capacity;static size_t npos;};std::ostream& operator<<(std::ostream& os, const string& str);std::istream& operator>>(std::istream& is, string& str);}

实现

#define _CRT_SECURE_NO_WARNINGS 1
#include "String.h"using namespace mystring;size_t string::npos = -1;mystring::string::string(const char* str):_size(strlen(str))
{_capacity = _size == 0 ? 3 : _size + 1;_str = new char[_capacity];strcpy(_str, str);
}mystring::string::string(const string& obj):_size(obj._size),_capacity(obj._capacity)
{_str = new char[_capacity];strcpy(_str, obj._str);
}void string::PsuhBack(char ch)
{if (_size + 1>= _capacity){//扩容Reserve(_capacity * 2);}_str[_size] = ch;_size++;_str[_size] = '\0';//insert(_size, ch);
}string& mystring::string::Append(const char* str)
{size_t len = strlen(str);if (_size + len >= _capacity){//扩容Reserve(_capacity + len);}strcpy(_str + _size, str);_size += len;return *this;
}string& mystring::string::Insert(size_t pos, char ch)
{assert(pos <= _size);if (_size + 1>= _capacity){//扩容Reserve(_capacity * 2);}int end = _size + 1;while (end > pos){_str[end] = _str[end - 1];end--;}_str[pos] = ch;_size++;return *this;
}string& mystring::string::Insert(size_t pos, const char* str)
{assert(pos <= _size);size_t len = strlen(str);if (_size + len >= _capacity){//扩容Reserve(_capacity + len);}size_t end = _size + len;while (end - len + 1> pos){_str[end] = _str[end - len];end--;}strncpy(_str + pos, str, len);_size += len;return *this;}string& mystring::string::operator+=(char ch)
{PsuhBack(ch);return *this;
}string& mystring::string::operator+=(const char* str)
{Append(str);return *this;
}void mystring::string::Reserve(size_t capacity)
{//比原空间小,不扩容,防止单独调用if (capacity > _capacity){char* tmp = new char[capacity];strcpy(tmp, _str);delete[] _str;_str = tmp;_capacity = capacity;}}void mystring::string::Resize(size_t capacity, char ch)
{//比元空间小,不缩容if (capacity > _capacity){Reserve(capacity + 1);memset(_str + _size, ch, capacity - _size);_size = capacity;_str[_size] = '\0';}else{_str[capacity] = '\0';_size = capacity;}
}string& mystring::string::Erase(size_t pos, size_t n)
{assert(pos < _size);//分三种情况,n全删和部分size_t end = pos;if (n == npos || pos + n >= _size){_str[pos] = '\0';//长度改为pos_size = pos;}else{/*while (end < _size - n){_str[end] = _str[end + n];end++;}_str[_size - n] = '\0';*/strcpy(_str + pos, _str + pos + n);_size -= n;}return *this;}void mystring::string::Clear()
{_size = 0;_str[_size] = '\0';
}size_t mystring::string::Find(char ch, size_t pos)
{assert(pos < _size);for (size_t i = pos; i < _size; i++){if (_str[i] == ch){return i;}}return npos;
}size_t mystring::string::Find(char* str, size_t pos)
{assert(pos < _size);char* p = strstr(_str + pos, str);if (p == nullptr){return npos;}else{return p - _str;}}void mystring::string::Swap(string& obj)
{std::swap(_str, obj._str);std::swap(_size, obj._size);std::swap(_capacity, obj._capacity);
}string& mystring::string::operator=(const string& obj)
{if (this != &obj){char* tmp = new char[obj._capacity];strcpy(tmp, obj._str);delete[] _str;_str = tmp;_size = obj._size;_capacity = obj._capacity;}return *this;
}std::ostream& mystring::operator<<(std::ostream& os, const string& str)
{for (auto ch : str){os << ch;}return os;
}std::istream& mystring::operator>>(std::istream& is, string& str)
{//cin遇到空格会退出str.Clear();char ch = is.get();//先存入临时数组,减少扩容次数char buff[128];size_t i = 0;while (ch != ' ' && ch != '\n'){buff[i++] = ch;if (i == 127){buff[127] = '\0';str += buff;i = 0;}ch = is.get();}//没有放入的if (i != 0){buff[i] = '\0';str += buff;}return is;/*str.Clear();char ch = is.get();char buff[128];size_t i = 0;while (ch != ' ' && ch != '\n'){buff[i++] = ch;if (i == 127){buff[127] = '\0';str += buff;i = 0;}ch = is.get();}if (i != 0){buff[i] = '\0';str += buff;}return is;*/}

测试

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string>
#include "String.h"
using namespace mystring;//void printstring(const string& s)
//{
//	string::cosnt_iterator it = s.begin();
//	while (it != s.end())
//	{
//		printf("%c", *it);
//		it++;
//	}
//}int main()
{string s1("abcd");std::string s2("abcd");//string s2("hello nih");//string::iterator it = s1.begin();/*for (size_t i = 0; i < s1.size(); i++){printf("%c",s1[i]);}*//*while (it != s1.end()){printf("%c", *it);it++;}*///s1 += 'a';//s1 += 'b';// += 'c';/*s1.Insert(0, 'y');s1.Insert(0, 'x');s1.Insert(2, "hello");*///s1.Insert(2, "hello");//s1.reserve();//s1.Erase(2,1);//s1.resize(10, 'x');//printf("%zd\n", s1.Find('b'));//printf("%zd\n", s2.find('b'));/*s2 += '\0';s2 += " www.nihao";s2.clear();*///s1 += '\0';//s1 += " www.he";std::cin >> s1;//std::cin >> s2;//string s2("world");//s2 = s1;//printf("size = %d\n capacity = %d\n%s\n", s1.size(), s1.capacity(), s1.c_str());//printf("s1 = s2 %d", s1 >= s2);//printstring(s1);std::cout << s1;return 0;
}

注意事项

容量默认比长度多一个,存储的\0
构造函数采用缺省构造,如果无参,默认为空字符串,如果为空指针,strlen计算长度会报错。因为容量依赖于长度,所以初始化列表先对size初始化。长度0时容量初始化为3,存储\0
插入功能注意0位置的插入,从size处开始会出错,因为size_t不会小于0的问题.所以选择从\0下一个位置开始挪
resize和reserve不会缩小容量,只会改变长度,resize判断两种情况,容量小于和大于目前的容量
erase如果长度是npos,就从pos位置全部删除,也需要分全删和部分删的情况
为了适应const对象调用下标,重载一个[]运算符,常成员函数返回常对象
swap比std的函数好的地方在于不需要构造,只需要交换三个成员变量
<<输出和c_str的区别,遇到\0c_str会停下来,<<按照长度打印
>>功能里cin遇到空格和换行会自动停下来,不会获取这个字符,导致while无限循环.所以改用io的get函数,空格和换行也会读取,用一个临时数组存够后一起放入对象里,避免多次扩容的浪费

vs的容量是默认15,如果超出则1.5倍扩容。而g++2倍扩容

写时拷贝

在浅拷贝的基础上增加了引用计数的方式
写时拷贝
写时拷贝的缺陷

扩展

测试时string的正确写法
STL的string类怎么了

相关文章:

  • python和shell脚本,每隔五分钟将远端服务器中的文件夹数据下载到跳板机
  • 1千多条中医中药知识及问答ACCESS\EXCEL数据库
  • 微信添加好友频繁的误区有哪些?
  • 第一章 深度学习发展概述
  • 代码随想录算法训练营day14 | 二叉树的递归遍历、二叉树的迭代遍历、二叉树的统一迭代
  • Nodejs 第五十四章(net)
  • 讲解linux下的Qt如何编译oracle的驱动库libqsqloci.so
  • R语言基础的代码语法解译笔记
  • 通过OceanBase 3.x中not in无法走hash连接的变化,来看OB优化器的发展
  • 2024蓝桥杯每日一题(区间合并)
  • pdf也可以制作成可翻页的电子书吗?
  • sensitive-word 敏感词 违规文字检测
  • python字符串转换成字典
  • 【论文速读】| 大语言模型引导的协议模糊测试
  • 【Java探索之旅】运算符解析 算术运算符,关系运算符
  • 【css3】浏览器内核及其兼容性
  • 【附node操作实例】redis简明入门系列—字符串类型
  • Android路由框架AnnoRouter:使用Java接口来定义路由跳转
  • create-react-app做的留言板
  • JavaScript DOM 10 - 滚动
  • Js基础——数据类型之Null和Undefined
  • Linux快速复制或删除大量小文件
  • Python 反序列化安全问题(二)
  • Vue源码解析(二)Vue的双向绑定讲解及实现
  • 第十八天-企业应用架构模式-基本模式
  • 给新手的新浪微博 SDK 集成教程【一】
  • 关于Java中分层中遇到的一些问题
  • 漂亮刷新控件-iOS
  • 微信小程序:实现悬浮返回和分享按钮
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • 优化 Vue 项目编译文件大小
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • ​TypeScript都不会用,也敢说会前端?
  • ###C语言程序设计-----C语言学习(6)#
  • #《AI中文版》V3 第 1 章 概述
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (delphi11最新学习资料) Object Pascal 学习笔记---第7章第3节(封装和窗体)
  • (附源码)springboot助农电商系统 毕业设计 081919
  • (十八)SpringBoot之发送QQ邮件
  • .NET 使用 XPath 来读写 XML 文件
  • .NET高级面试指南专题十一【 设计模式介绍,为什么要用设计模式】
  • .pop ----remove 删除
  • .project文件
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • @font-face 用字体画图标
  • [ 云计算 | AWS 实践 ] Java 如何重命名 Amazon S3 中的文件和文件夹
  • [2018][note]用于超快偏振开关和动态光束分裂的all-optical有源THz超表——
  • [android] 看博客学习hashCode()和equals()
  • [BZOJ1008][HNOI2008]越狱
  • [CF226E]Noble Knight's Path
  • [dart学习]第四篇:函数
  • [Docker]四.Docker部署nodejs项目,部署Mysql,部署Redis,部署Mongodb