C++ 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; }
(本章完)