C++ string模拟实现
- string模拟实现(部分接口)
C++的string类是一个类模板,用于表示和操作任何字符类型的字符串。 string类内部使用字符数组来存储字符,但是所有的内存管理,分配和空终止都由string类自己处理,所以使用起来很方便。string类的长度可以在运行时改变,因为它使用动态内存分配类似于vector。
string类提供了许多成员函数和运算符重载,用于进行字符串的创建,赋值,连接,比较,查找,替换,插入,删除等操作。你可以使用下标运算符[]或at()函数来访问字符串中的单个字符。你也可以使用c_str()或data()函数来获取字符串的C风格表示形式。
string模拟实现(部分接口)
官方C++string类:(string)
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<string>
using namespace std;
#include <assert.h>namespace hsl
{class string{public:typedef char* iterator;//构造函数string(const char* str = ""):_size(strlen(str)), _capacity(_size){_str = new char[_capacity + 1];strcpy(_str, str);}//string(const string& s);//string& operator=(const string& s);//析构函数~string(){delete[] _str;_str = nullptr;_size = _capacity = 0;}//// iterator//返回第一个位置的指针iterator begin(){return _str;}//返回最后一个位置的指针iterator end(){return _str + _size;}/// modify//尾插字符void push_back(char c){if (_size == _capacity){reserve(_capacity == 0 ? 4 : _capacity * 2);}_str[_size] = c;_size++;_str[_size] = '\0';}//尾插字符string& operator+=(char c){push_back(c);return *this;}//尾插字符串void append(const char* str){size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}strcpy(_str + _size, str);_size += len;}//重载+=运算符(尾插字符串)string& operator+=(const char* str){append(str);return *this;}//void clear();//void swap(string& s);//以字符串的形式返回const char* c_str()const{return _str;}///返回数据个数size_t size()const{return _size;}//返回容量大小size_t capacity()const{return _capacity;}//判断是否为空bool empty()const{return (_size == 0 || _capacity == 0);}//如果 n 小于当前容器大小,则内容将减少到其前 n 个元素,删除超出的元素(并销毁它们)。
//如果 n 大于当前容器大小,则通过在末尾插入所需数量的元素来扩展内容,以达到 n 的大小。如果指定了 //val,则新元素将初始化为 val 的副本,否则,它们将被值初始化。
//如果 n 也大于当前容器容量,则会自动重新分配分配的存储空间。void resize(size_t n, char c = '\0'){if (n < _size){_str[_size] = c;_size = n;}if (n > _size){if (n > _capacity){reserve(n);}int x = _size;_size = n;while (x < n){_str[x] = c;x++;}_str[n] = '\0';}}//扩容void reserve(size_t n){if (n > _capacity){char* ch = new char[n + 1];strcpy(ch, _str);delete[] _str;_str = ch;_capacity = n;}}///[]重载运算符char& operator[](size_t index){assert(index < _size);return _str[index];}//[]重载运算符(重载函数)const char& operator[](size_t index)const{assert(index < _size);return _str[index];}///relational operators//<重载运算符bool operator<(const string& s){return strcmp(_str, s._str) < 0;}//<=重载运算符bool operator<=(const string& s){return (_str < s._str) || (_str == s._str);}//>重载运算符bool operator>(const string& s){return !((_str <= s._str));}//>=重载运算符bool operator>=(const string& s){return !(_str < s._str);}//==重载运算符bool operator==(const string& s){return strcmp(_str, s._str) == 0;}//!=重载运算符bool operator!=(const string& s){return !(_str == s._str);}// 返回c在string中第一次出现的位置//size_t find(char c, size_t pos = 0) const;// 返回子串s在string中第一次出现的位置//size_t find(const char* s, size_t pos = 0) const;// 在pos位置上插入字符c/字符串str,并返回该字符的位置string& insert(size_t pos, char c){assert(pos <= _size);if (_size == _capacity){reserve(_capacity == 0 ? 4 : _capacity * 2);}int end = (int)_size;while (end >= (int)pos){_str[end + 1] = _str[end];--end;}_str[pos] = c;_size++;return *this;}//在pos位置插入字符串string& insert(size_t pos, const char* str){assert(pos <= _size);int len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}int end = _size;while (end >= (int)pos){_str[end + len] = _str[end];--end;}_size += len;int n = pos + len;int i = 0;while (pos < n){_str[pos++] = str[i++];}return *this;}// 删除pos位置上的元素,并返回该元素的下一个位置string& erase(size_t pos, size_t len){assert(pos < _size);size_t end = _size;//assert((end - pos) >= len);if (pos + len >= _size){_str[pos] = '\0';_size = pos;}else{while (pos <= (end - len + 1)){_str[pos] = _str[pos + len];pos++;}_size -= len;}return *this;}//清空数据(不删除数据)void clear(){_str[0] = '\0';_size = 0;}//传统写法s1(s2)//string(const string& s)//{// _str = new char[s._capacity + 1];// strcpy(_str, s._str);// _size = s._size;// _capacity = s._capacity;//}s1 = s2;//string& operator=(const string& s)//{// if (this != &s)// {// char* tmp = new char[s._capacity+1];// strcpy(tmp, s._str);// delete[] _str;// _str = tmp;// _size = s._size;// _capacity = s._capacity;// }// return *this;//} //交换void swap(string& s){std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);}//s1(s2)//拷贝构造string(const string& s):_str(nullptr), _size(0), _capacity(0){string tmp(s._str);swap(tmp);}//s1 = s2;//赋值重载string& operator=(string s){swap(s);return *this;}private:char* _str;//字符指针size_t _size;//字符个数size_t _capacity;//容量};//输出流ostream& operator<<(ostream& _cout, const string& s){for (size_t i = 0; i < s.size(); i++){cout << s[i];}return _cout;}//istream& operator>>(istream& _cin, string& s)//{// s.clear();// char ch;// ch = _cin.get();// while (ch != ' ' && ch != '\n')// {// s += ch;// ch = _cin.get();// }// return _cin;//}//输入流istream& operator>>(istream& _cin, string& s){s.clear();char ch;char buff[129];int i = 0;ch = _cin.get();while (ch != ' ' && ch != '\n'){buff[i++] = ch;if (i == 128){buff[i] = '\0';s += buff;i = 0;}ch = _cin.get();}if (i != 0){buff[i] = '\0';s += buff;}return _cin;}void test_string3(){string s1;cin >> s1;cout << s1 << endl;cout << s1.size() << endl;cout << s1.capacity() << endl;}}int main()
{ hsl::test_string3();return 0;
}
(本章完)