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类怎么了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/733398.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WebGL 之创建 2D 内容

引入 glMatrix 库 该项目使用了 glMatrix 库来执行其矩阵操作&#xff0c;因此需要引入它。本次示例通过 CDN 形式引入使用。 <!doctype html> <html lang"en"><head><meta charset"utf-8" /><title>WebGL Demo</title…

北斗导航 | 十四种抗差稳健估计(抗差M估计)方法(算法公式)

===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== 稳健估计(M估计) 1、Huber法2、残差绝对和最小法3、L1-L2法

Joe主题网站

一款博客网站源码 发现源码为大家内置了主题 清爽又强大真正的永久可用的一条源码&#xff0c;该版本为整合版本&#xff0c;内置了Joe主题&#xff0c;搭建后直接启用即可~ 安装环境要求&#xff1a; PHP 7.2 以上 MySQL, PostgreSQL, SQLite 任意一种数据库支持&#xff0c;…

获取webshell的十种方法

一、直接上传获取webshell 这种对php和jsp的一些程序比较常见&#xff0c;MolyX BOARD就是其中一例&#xff0c;直接在心情图标管理上传。php类型&#xff0c;虽然没有提示&#xff0c;其实已经成功了&#xff0c;上传的文 件url应该是http://forums/images/smiles/下&#xf…

Synthetic Temporal Anomaly Guided End-to-End Video Anomaly Detection 论文阅读

Synthetic Temporal Anomaly Guided End-to-End Video Anomaly Detection 论文阅读 Abstract1. Introduction2. Related Work3. Methodology3.1. Architecture3.1.1 Autoencoder3.1.2 Temporal Pseudo Anomaly Synthesizer 3.2. Training3.3. Anomaly Score 4. Experiments4.1.…

【C++ 学习】拷贝构造你了解多少?

文章目录 1. 拷贝构造的引入2. 拷贝构造的引用场景 1. 拷贝构造的引入 拷贝构造函数&#xff1a;只有单个形参&#xff0c;该形参是对本类类型对象的引用(一般常用const修饰)&#xff0c;在用已存在的类类型对象创建新对象时由编译器自动调用&#xff1b; 特征&#xff1a; ① …

CMakeLists.txt文件介绍

简化的 CMakeLists.txt 文件的例子&#xff0c;它展示了如何构建一个库和一个可执行文件&#xff0c;以及如何链接它们。这个例子假设您的项目结构如下&#xff1a; project_root/ CMakeLists.txt src/ lib/ Beidou.h Beidou.cpp test/ BeidouTest.cpp CMakeLists.txt…

Day40| 343 整数拆分 96 不同的二叉搜索树

目录 343 整数拆分 96 不同的二叉搜索树 343 整数拆分 class Solution { public:int integerBreak(int n) {vector<int> dp(n 1);dp[2] 1;for(int i 3; i < n; i){for(int j 1; j < i / 2; j){dp[i] max(dp[i], max((i - j) * j, dp[i - j] * j));}co…

gin golang Invalid validation tag on field ‘AId‘

结构体如下type CreateParams struct {AId uint json:"a_id" binding:"required,"BId uint json:"b_id" binding:"required,"} 运行时报错&#xff1a;Invalid validation tag on field AId 原因&#xff1a;在binding中&#…

arcgis 栅格数据处理2——栅格转地级市(栅格转矢量图)

1. 获取空间分析权限&#xff08;解决无法执行所选工具问题&#xff09; 选中“自定义”中的“扩展模块” 在弹出的模块中选中能选的模块&#xff0c;此处需要选择“spatial analysis”以进行下一步分析 3. 将栅格数据转为整数型&#xff08;解决无法矢量化&#xff09; 选…

算法->位运算

有关位运算的操作符 >> <<&|^~ 常见位运算操作 给定一个数&#xff0c;确定它的二进制中第x位是0还是1 (n >> x) & 1; 将一个数n的二进制中第x位修改为1 n | (1 << x) 将一个数n的二进制中第x位修改为0 n & (~(1 << x)) 提…

MySQL从入门到实战

MySQL从入门到实战 1.连接数据库 在操作数据库之前&#xff0c;需要连接它&#xff0c;输入命令&#xff1a;mysql -u用户名 -p密码。 2.创建数据库 创建完数据库之后我们可以通过show databases;命令查看MySQL中已存在的数据库。[请注意&#xff1a;数据库名区分大小写。] 3…

OpenJDK 目前主要发展方向

Loom&#xff1a;得赶紧解决 synchronized pin 线程的问题&#xff08;据说 Java 23 会解决&#xff0c;现在有预览版&#xff09;。各个 Java 库需要改造原来使用 ThreadLocal 的方式&#xff1a;如果是为了穿参数&#xff0c;则可以使用 ScopedLocal&#xff1b;如果是对象池…

Android 获取Sms

Android 获取Sms 本篇文章记录下android下获取短信列表. 1: 申请权限 <uses-permission android:name"android.permission.READ_SMS" />2: 获取短信内容列表 private void readSms() {String[] projection {"_id", "address", "b…

nginx配置支持ipv6访问,ipv4改造ipv6

一、前言 本地测试nginx部署的web系统支持ipv6地址访问。 二、本机ipv6地址 cmd ipconfig 找到IPv6地址 其中带有%号其实是临时分配得到地址 我们可以ping一下看看 另一种ping的方式 加上中括号 还有就是去掉%号 三、nginx增加配置 server块里增加 listen [::]:80; 四、测…

JavaWeb开发——html、 jsp(html 、js 、java源码)

1.前后端整体合一 在页面上&#xff0c;包含界面和业务数据处理 2.前后端分离 项目整体上分成前端部分和后端部分&#xff0c;相互独立 Jquery的核心 选择器----找到需要操作的Dom读取或者设置DOM的值或者属性事件的处理 一、jQuery选择器 $("标签类型")$("…

anaconda问题合集

目录 一. 万分注意 二. ImportError: DLL load failed while importing _ctypes: 找不到指定的模块。 1. 发生情况 2. 导致结果和解决方法 三. WARNING: A newer version of conda exists. 1. 在conda install 某库的时候 2. 解决方法 一. 万分注意 不要轻易使用 conda …

UE4升级UE5 蓝图节点变更汇总(4.26/27-5.2/5.3)

一、删除部分 Ploygon Editing删除 Polygon Editing这个在4.26、4.27中的插件&#xff0c;在5.1后彻底失效。 相关的蓝图&#xff0c;如编辑器蓝图 Generate mapping UVs等&#xff0c;均失效。 如需相关功能&#xff0c;请改成Dynamic Mesh下的方法。 GetSupportedClass删…

Java Collections 工具类

public static int binarySearch(List list,T key) 在 List 集合中查找某个元素的下标&#xff0c;但是 List 的元素 必须是 T 或 T的子类对象&#xff0c;而且必须是可比较大小的&#xff0c;即支持自然排序的。而且集合也事先必须是有序的&#xff0c;否则结果不确定。…

【CMake】总体认识

文章目录 体系架构 CMake根据CMakeLists.txt进行对项目的构建&#xff0c;至少有一个位于项目根目录下的顶层CMakeLists.txt&#xff0c;此外还可以在项目的其他目录下设置CMakeLists.txt负责本目录下的构建。顶层CMakeLists.txt负责设置整个项目的全局参数&#xff0c;比如最低…