commit c9e61a2f172fd7d9ff4f0f64085f3c507d1d63c0 Author: Lenyiin <569963146@qq.com> Date: Thu Sep 5 21:32:34 2024 +0800 博客 https://blog.lenyiin.com/cpp-string/ 的代码仓库 diff --git a/Linux/Makefile b/Linux/Makefile new file mode 100644 index 0000000..e087405 --- /dev/null +++ b/Linux/Makefile @@ -0,0 +1,6 @@ +string:String.cc + g++ -o $@ $^ + +.PHONY:clean +clean: + rm -f string \ No newline at end of file diff --git a/Linux/String.cc b/Linux/String.cc new file mode 100644 index 0000000..a4f73eb --- /dev/null +++ b/Linux/String.cc @@ -0,0 +1,251 @@ +#include "String.hpp" +using namespace std; +using namespace Lenyiin; + +// 测试遍历 +void test1() +{ + String s("abcdefghijklmn"); + + // 1. [] 下标运算符访问 + for (size_t i = 0; i < s.size(); i++) + { + cout << s[i] << " "; + } + cout << endl; + + // 2. iterator + String::iterator it = s.begin(); + while (it != s.end()) + { + cout << *it << " "; + ++it; + } + cout << endl; + + // 3. const_iterator + String::const_iterator cit = s.begin(); + while (cit != s.end()) + { + cout << *cit << " "; + ++cit; + } + cout << endl; + + // 4. 范围 for + for (const auto &ch : s) + { + cout << ch << " "; + } + cout << endl; + + // 5. 反向迭代器 riterator + String::riterator rit = s.rbegin(); + while (rit != s.rend()) + { + cout << *rit << " "; + --rit; + } + cout << endl; + + // 6. 反向迭代器 const_riterator + String::const_riterator crit = s.rbegin(); + while (crit != s.rend()) + { + cout << *crit << " "; + --crit; + } + cout << endl; +} + +void test2() +{ + // 默认构造函数 + String s1; + // 默认有参构造函数 + String s2("Hello Lenyiin"); + // 拷贝构造函数 + String s3(s2); + + // 输出 << 重载 + cout << "s1: " << s1 << endl; + cout << "s2: " << s2 << endl; + cout << "s3: " << s3 << endl; + + // 赋值 = 运算符重载 + s1 = s2; + cout << "s1: " << s1 << endl; +} + +void test3() +{ + String s1; + + // 尾插 + s1.push_back('H'); + s1.push_back('e'); + s1.push_back('l'); + s1.push_back('l'); + s1.push_back('o'); + cout << "s1: " << s1 << endl; + + // 测试 size() capacity() + cout << s1.size() << " " << s1.capacity() << endl; + + // 追加一个字符 + s1.append(' '); + // 追加一个字符串 + s1.append("Lenyiin"); + cout << "s1: " << s1 << endl; + cout << s1.size() << " " << s1.capacity() << endl; + + // += + s1 += " abc"; + cout << "s1: " << s1 << endl; + cout << s1.size() << " " << s1.capacity() << endl; + + // 测试 resize + s1.resize(7); + cout << "s1: " << s1 << endl; + cout << s1.size() << " " << s1.capacity() << endl; + + // 测试 reserve + s1.reserve(20); + cout << "s1: " << s1 << endl; + cout << s1.size() << " " << s1.capacity() << endl; + + // += s + String s2("aaa"); + s1 += s2; + s1.append(s2); + cout << "s: " << s1 << endl; + cout << s1.size() << " " << s1.capacity() << endl; + + // insert + s1.insert(1, "abc"); + cout << "s: " << s1 << endl; + cout << s1.size() << " " << s1.capacity() << endl; + s1.insert(6, s2); + cout << "s: " << s1 << endl; + cout << s1.size() << " " << s1.capacity() << endl; + + // 测试尾删 + s1.pop_back(); + cout << "s: " << s1 << endl; + cout << s1.size() << " " << s1.capacity() << endl; + + // 测试 erase + s1.erase(10, 5); + cout << "s: " << s1 << endl; + cout << s1.size() << " " << s1.capacity() << endl; + s1.erase(3); + cout << "s: " << s1 << endl; + cout << s1.size() << " " << s1.capacity() << endl; +} + +void test4() +{ + String s1("aaaa"); + String s2("aabb"); + String s3("aaaa"); + String s4("abaa"); + String s5("abcd"); + + if (s1 < s2) + { + cout << s1 << " < " << s2 << endl; + } + else + { + cout << s1 << " >= " << s2 << endl; + } + + if (s4 > s2) + { + cout << s4 << " > " << s2 << endl; + } + else + { + cout << s4 << " <= " << s2 << endl; + } + + if (s1 == s3) + { + cout << s1 << " == " << s2 << endl; + } + + if (s1 != s2) + { + cout << s1 << " != " << s2 << endl; + } +} + +void test5() +{ + String s("abcd Lenyiin efghi Lenyiin jklmn"); + + // 查找字符 + size_t pos = s.find('b'); + if (pos != String::npos) + { + cout << "找到啦!下标是: " << pos << endl; + } + else + { + cout << "没找到!" << endl; + } + + // 查找字符串 + pos = s.find("Lenyiin"); + if (pos != String::npos) + { + cout << "找到啦!下标是: " << pos << endl; + } + else + { + cout << "没找到!" << endl; + } + + // 反向查找字符 + pos = s.rfind('x'); + if (pos != String::npos) + { + cout << "找到啦!下标是: " << pos << endl; + } + else + { + cout << "没找到 x !" << endl; + } + + // 反向查找字符串 + pos = s.rfind("Lenyiin"); + if (pos != String::npos) + { + cout << "找到啦!下标是: " << pos << endl; + } + else + { + cout << "没找到!" << endl; + } + + // 截取字符串 + String s2 = s.substr(5, 7); + cout << "截取到的字符串是: " << s2 << endl; + + // 测试 >> 运算符 + cout << "请输入字符: "; + String s3; + cin >> s3; + cout << "你输入的是: " << s3 << endl; +} + +int main() +{ + // test1(); + // test2(); + // test3(); + // test4(); + test5(); + + return 0; +} \ No newline at end of file diff --git a/Linux/String.hpp b/Linux/String.hpp new file mode 100644 index 0000000..f5656d9 --- /dev/null +++ b/Linux/String.hpp @@ -0,0 +1,573 @@ +#pragma once + +#include +#include +#include + +namespace Lenyiin +{ + // 实现一个支持增删查改的 string + class String + { + public: + // 迭代器 + typedef char *iterator; + typedef const char *const_iterator; + typedef char *riterator; + typedef const char *const_riterator; + + iterator begin() // 返回首地址 + { + return _str; + } + + iterator end() // 返回尾地址 + { + return _str + _size; + } + + const_iterator begin() const + { + return _str; + } + + const_iterator end() const + { + return _str + _size; + } + + riterator rbegin() + { + return _str + _size - 1; + } + + riterator rend() + { + return _str - 1; + } + + const_riterator rbegin() const + { + return _str + _size - 1; + } + + const_riterator rend() const + { + return _str - 1; + } + + public: + //// 默认构造函数:创建一个空字符串 + // String() + // : _str(nullptr), _size(0), _capacity(0) + //{ + // } + + //// 带参数的构造函数:从C风格字符串创建String对象 + // String(const char* str) { + // if (str) { + // _size = _capacity = strlen(str); + // _str = new char[_size + 1]; // 分配内存,+1是为了存储终止符'\0' + // strcpy(_str, str); // 将字符串内容复制到data指向的内存 + // } + // else { + // _str = nullptr; + // _size = _capacity = 0; + // } + // } + + // 进阶写法 + // 默认构造函数 + String(const char *str = "") // 默认构造函数 + : _str(new char[strlen(str) + 1]), _size(strlen(str)), _capacity(_size) + { + strcpy(_str, str); + } + + // 拷贝构造函数:深拷贝 + // String(const String& s) // 拷贝构造函数 + // : _str(new char[s._capacity + 1]), _size(s._size), _capacity(s._capacity) + //{ + // strcpy(_str, s._str); + //} + + // 进阶写法 + // 拷贝构造 复用默认构造 + String(const String &s) + : String(s._str) + { + } + + // 赋值运算 + // 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); + } + + String &operator=(String s) + { + this->Swap(s); + + return *this; + } + + String &operator=(const char *str) + { + String s(str); + this->Swap(s); + + return *this; + } + + // 移动构造函数 + String(String &&s) noexcept + : _str(s._str), _size(s._size), _capacity(s._capacity) + { + s._str = nullptr; + s._size = s._capacity = 0; + } + + // 移动赋值运算符 + String &operator=(String &&s) noexcept + { + if (this != &s) + { + delete[] _str; // 释放当前对象的内存 + + _str = s._str; // 接管资源 + _size = s._size; + _capacity = s._capacity; + + s._str = nullptr; // 将other对象重置为默认状态 + s._size = s._capacity = 0; + } + + return *this; + } + + // 重载 [] 运算符 + char &operator[](size_t pos) + { + assert(pos < _size); + + return _str[pos]; + } + + const char &operator[](size_t pos) const + { + assert(pos < _size); + + return _str[pos]; + } + + // 获取私有成员 + size_t size() const // 获取有效字符个数 + { + return _size; + } + + size_t capacity() const // 获取有效容量 + { + return _capacity; + } + + const char *c_str() const // 返回字符串 + { + return _str; + } + + // 析构函数 + ~String() + { + delete[] _str; + _str = nullptr; + _size = _capacity = 0; + } + + // 开辟空间 + void reserve(size_t newcapacity) + { + if (newcapacity > _capacity) + { + char *newstr = new char[newcapacity + 1]; + strcpy(newstr, _str); + delete[] _str; + _str = newstr; + _capacity = newcapacity; + } + } + + // 设置指定大小, 并初始化 + void resize(size_t newsize, char ch = '\0') + { + if (newsize < _size) + { + _size = newsize; + _str[_size] = '\0'; + } + else + { + if (newsize > _capacity) + { + reserve(newsize); + } + for (size_t i = _size; i < newsize; i++) + { + _str[i] = ch; + } + _size = newsize; + _str[_size] = '\0'; + } + } + + // 尾插 + void push_back(char ch) // 尾插一个字符 + { + if (_size == _capacity) + { + size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2; + reserve(newcapacity); + } + + _str[_size++] = ch; + _str[_size] = '\0'; + } + + // 追加 + void append(const char ch) + { + push_back(ch); + } + + void append(const char *str) // 追加一个字符串 + { + size_t len = strlen(str); + if (_size + len > _capacity) + { + reserve(_size + len); + } + + strcpy(_str + _size, str); + _size += len; + } + + void append(const String &s) // 追加一个对象 + { + append(s._str); + } + + // 运算符 += 重载 + String &operator+=(const char ch) + { + this->push_back(ch); + + return *this; + } + + String &operator+=(const char *str) + { + this->append(str); + + return *this; + } + + String &operator+=(const String &s) + { + append(s); + + return *this; + } + + // 任意位置插入字符 + String &insert(size_t pos, char ch) + { + assert(pos <= _size); + + if (_size == _capacity) + { + size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2; + reserve(newcapacity); + } + + int end = _size; + while (end >= (int)pos) + { + _str[end + 1] = _str[end]; + --end; + } + _str[pos] = ch; + ++_size; + + return *this; + } + + // 任意位置插入字符串 + String &insert(size_t pos, const char *str) + { + assert(pos <= _size); + + // 1. 如果空间不够就扩容 + size_t len = strlen(str); + if (_size + len > _capacity) + { + reserve(_size + len); + } + + // 2. 挪动数据 + int end = _size; + while (end >= (int)pos) + { + _str[end + len] = _str[end]; + --end; + } + + // 3. 插入数据 + strncpy(_str + pos, str, len); + _size += len; + + return *this; + } + + // 任意位置插入一个对象 + String &insert(size_t pos, const String &s) + { + return insert(pos, s._str); + } + + // 删除 + String &erase(size_t pos = 0, size_t len = npos) + { + assert(pos < _size); + + if (len >= _size - pos) + { + _str[pos] = '\0'; + _size = pos; + } + else + { + while (pos <= _size - len) + { + _str[pos] = _str[pos + len]; + ++pos; + } + _size -= len; + } + + return *this; + } + + // 尾删 + void pop_back() + { + assert(_size > 0); + + --_size; + _str[_size] = '\0'; + } + + // 运算符 < 重载 + bool operator<(const String &s) + { + int ret = strcmp(_str, s._str); + + return ret < 0; + } + + // 运算符 == 重载 + bool operator==(const String &s) + { + int ret = strcmp(_str, s._str); + + return ret == 0; + } + + // 运算符 <= 重载 + bool operator<=(const String &s) + { + return *this < s || *this == s; + } + + // 运算符 > 重载 + bool operator>(const String &s) + { + int ret = strcmp(_str, s._str); + + return ret > 0; + } + + // 运算符 >= 重载 + bool operator>=(const String &s) + { + return !(*this < s); + } + + // 运算符 != 重载 + bool operator!=(const String &s) + { + return !(*this == s); + } + + // 查找字符 + 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; + } + + // 查找字符串 + size_t find(const char *str, size_t pos = 0) const + { + char *p = strstr(_str, str); + + if (p == nullptr) + { + return npos; + } + else + { + return p - _str; + } + } + + // 查找对象 + size_t find(const String &s, size_t pos = 0) const + { + return find(s._str, pos); + } + + // 反向查找字符串 + size_t rfind(char ch, size_t pos = npos) const + { + if (pos == npos) + { + pos = _size - 1; + } + + for (int i = pos; i >= 0; i--) + { + if (_str[i] == ch) + { + return i; + } + } + + return npos; + } + + // 反向查找字符串 + size_t rfind(const char *str, size_t pos = npos) + { + size_t len = strlen(str); + if (len > _size) + { + return npos; + } + + if (pos >= _size) + { + pos = _size - 1; + } + + for (size_t i = pos; i != npos; i--) + { + if (strncmp(_str + i, str, len) == 0) + { + return i; + } + } + + return npos; + } + + String substr(size_t pos = 0, size_t len = npos) const + { + assert(pos < _size); + + if (len == npos || len + pos > _size) + { + len = _size - pos; + } + + char *buffer = new char[len + 1]; + strncpy(buffer, _str + pos, len); + buffer[len] = '\0'; + + return String(buffer); + } + + // 清空 + void clear() + { + _size = 0; + _str[_size] = '\0'; + } + + private: + char *_str; + size_t _size; // 记录已经存储了多少有效字符 + size_t _capacity; // 记录能存储多少有效字符 '\0' 结尾 但不作为有效字符 + + public: + static size_t npos; // size_t -> unsigned long long -1 是一个极大的数 + }; + + size_t String::npos = -1; + + std::ostream &operator<<(std::ostream &_cout, const String &s) + { + for (size_t i = 0; i < s.size(); i++) + { + _cout << s[i]; + } + return _cout; + } + + std::istream &operator>>(std::istream &_cin, String &s) + { + while (true) + { + char ch; + //_cin >> ch; + ch = _cin.get(); + + // if (ch == '\n') // 通过换行分割 + if (ch == ' ' || ch == '\n') + { + break; + } + else + { + s += ch; + } + } + + return _cin; + } +} \ No newline at end of file diff --git a/Linux/string b/Linux/string new file mode 100644 index 0000000..1fc5f66 Binary files /dev/null and b/Linux/string differ diff --git a/Windows_String/.vs/Windows_String/FileContentIndex/2a050413-1947-4a88-bd2e-3cad1591490d.vsidx b/Windows_String/.vs/Windows_String/FileContentIndex/2a050413-1947-4a88-bd2e-3cad1591490d.vsidx new file mode 100644 index 0000000..1f577e9 Binary files /dev/null and b/Windows_String/.vs/Windows_String/FileContentIndex/2a050413-1947-4a88-bd2e-3cad1591490d.vsidx differ diff --git a/Windows_String/.vs/Windows_String/FileContentIndex/4e5f41ff-4ac0-4863-920a-f6c10243e16b.vsidx b/Windows_String/.vs/Windows_String/FileContentIndex/4e5f41ff-4ac0-4863-920a-f6c10243e16b.vsidx new file mode 100644 index 0000000..b662b28 Binary files /dev/null and b/Windows_String/.vs/Windows_String/FileContentIndex/4e5f41ff-4ac0-4863-920a-f6c10243e16b.vsidx differ diff --git a/Windows_String/.vs/Windows_String/FileContentIndex/ed67d926-fd2d-4732-8cad-e10c38a0e4a5.vsidx b/Windows_String/.vs/Windows_String/FileContentIndex/ed67d926-fd2d-4732-8cad-e10c38a0e4a5.vsidx new file mode 100644 index 0000000..06693ff Binary files /dev/null and b/Windows_String/.vs/Windows_String/FileContentIndex/ed67d926-fd2d-4732-8cad-e10c38a0e4a5.vsidx differ diff --git a/Windows_String/.vs/Windows_String/v17/.suo b/Windows_String/.vs/Windows_String/v17/.suo new file mode 100644 index 0000000..7885dda Binary files /dev/null and b/Windows_String/.vs/Windows_String/v17/.suo differ diff --git a/Windows_String/.vs/Windows_String/v17/Browse.VC.db b/Windows_String/.vs/Windows_String/v17/Browse.VC.db new file mode 100644 index 0000000..6dc9868 Binary files /dev/null and b/Windows_String/.vs/Windows_String/v17/Browse.VC.db differ diff --git a/Windows_String/.vs/Windows_String/v17/ipch/AutoPCH/1971130f98893a61/STRING.ipch b/Windows_String/.vs/Windows_String/v17/ipch/AutoPCH/1971130f98893a61/STRING.ipch new file mode 100644 index 0000000..9bb2347 Binary files /dev/null and b/Windows_String/.vs/Windows_String/v17/ipch/AutoPCH/1971130f98893a61/STRING.ipch differ diff --git a/Windows_String/.vs/Windows_String/v17/ipch/AutoPCH/44c0da0fb111d6d8/STRING.ipch b/Windows_String/.vs/Windows_String/v17/ipch/AutoPCH/44c0da0fb111d6d8/STRING.ipch new file mode 100644 index 0000000..613b180 Binary files /dev/null and b/Windows_String/.vs/Windows_String/v17/ipch/AutoPCH/44c0da0fb111d6d8/STRING.ipch differ diff --git a/Windows_String/String.cpp b/Windows_String/String.cpp new file mode 100644 index 0000000..9f5d809 --- /dev/null +++ b/Windows_String/String.cpp @@ -0,0 +1,253 @@ +#define _CRT_SECURE_NO_WARNINGS +#include "String.hpp" +using namespace std; +using namespace Lenyiin; + + +// Ա +void test1() +{ + String s("abcdefghijklmn"); + + // 1. [] ± + for (size_t i = 0; i < s.size(); i++) + { + cout << s[i] << " "; + } + cout << endl; + + // 2. iterator + String::iterator it = s.begin(); + while (it != s.end()) + { + cout << *it << " "; + ++it; + } + cout << endl; + + // 3. const_iterator + String::const_iterator cit = s.begin(); + while (cit != s.end()) + { + cout << *cit << " "; + ++cit; + } + cout << endl; + + // 4. Χ for + for (const auto& ch : s) + { + cout << ch << " "; + } + cout << endl; + + // 5. riterator + String::riterator rit = s.rbegin(); + while (rit != s.rend()) + { + cout << *rit << " "; + --rit; + } + cout << endl; + + // 6. const_riterator + String::const_riterator crit = s.rbegin(); + while (crit != s.rend()) + { + cout << *crit << " "; + --crit; + } + cout << endl; +} + +void test2() +{ + // ĬϹ캯 + String s1; + // Ĭвι캯 + String s2("Hello Lenyiin"); + // 캯 + String s3(s2); + + // << + cout << "s1: " << s1 << endl; + cout << "s2: " << s2 << endl; + cout << "s3: " << s3 << endl; + + // ֵ = + s1 = s2; + cout << "s1: " << s1 << endl; +} + +void test3() +{ + String s1; + + // β + s1.push_back('H'); + s1.push_back('e'); + s1.push_back('l'); + s1.push_back('l'); + s1.push_back('o'); + cout << "s1: " << s1 << endl; + + // size() capacity() + cout << s1.size() << " " << s1.capacity() << endl; + + // ׷һַ + s1.append(' '); + // ׷һַ + s1.append("Lenyiin"); + cout << "s1: " << s1 << endl; + cout << s1.size() << " " << s1.capacity() << endl; + + // += + s1 += " abc"; + cout << "s1: " << s1 << endl; + cout << s1.size() << " " << s1.capacity() << endl; + + // resize + s1.resize(7); + cout << "s1: " << s1 << endl; + cout << s1.size() << " " << s1.capacity() << endl; + + // reserve + s1.reserve(20); + cout << "s1: " << s1 << endl; + cout << s1.size() << " " << s1.capacity() << endl; + + // += s + String s2("aaa"); + s1 += s2; + s1.append(s2); + cout << "s: " << s1 << endl; + cout << s1.size() << " " << s1.capacity() << endl; + + // insert + s1.insert(1, "abc"); + cout << "s: " << s1 << endl; + cout << s1.size() << " " << s1.capacity() << endl; + s1.insert(6, s2); + cout << "s: " << s1 << endl; + cout << s1.size() << " " << s1.capacity() << endl; + + // βɾ + s1.pop_back(); + cout << "s: " << s1 << endl; + cout << s1.size() << " " << s1.capacity() << endl; + + // erase + s1.erase(10, 5); + cout << "s: " << s1 << endl; + cout << s1.size() << " " << s1.capacity() << endl; + s1.erase(3); + cout << "s: " << s1 << endl; + cout << s1.size() << " " << s1.capacity() << endl; +} + +void test4() +{ + String s1("aaaa"); + String s2("aabb"); + String s3("aaaa"); + String s4("abaa"); + String s5("abcd"); + + if (s1 < s2) + { + cout << s1 << " < " << s2 << endl; + } + else + { + cout << s1 << " >= " << s2 << endl; + } + + if (s4 > s2) + { + cout << s4 << " > " << s2 << endl; + } + else + { + cout << s4 << " <= " << s2 << endl; + } + + if (s1 == s3) + { + cout << s1 << " == " << s2 << endl; + } + + if (s1 != s2) + { + cout << s1 << " != " << s2 << endl; + } +} + +void test5() +{ + String s("abcd Lenyiin efghi Lenyiin jklmn"); + + // ַ + size_t pos = s.find('b'); + if (pos != String::npos) + { + cout << "ҵ±: " << pos << endl; + } + else + { + cout << "ûҵ" << endl; + } + + // ַ + pos = s.find("Lenyiin"); + if (pos != String::npos) + { + cout << "ҵ±: " << pos << endl; + } + else + { + cout << "ûҵ" << endl; + } + + // ַ + pos = s.rfind('x'); + if (pos != String::npos) + { + cout << "ҵ±: " << pos << endl; + } + else + { + cout << "ûҵ x !" << endl; + } + + // ַ + pos = s.rfind("Lenyiin"); + if (pos != String::npos) + { + cout << "ҵ±: " << pos << endl; + } + else + { + cout << "ûҵ" << endl; + } + + // ȡַ + String s2 = s.substr(5, 7); + cout << "ȡַ: " << s2 << endl; + + // >> + cout << "ַ: "; + String s3; + cin >> s3; + cout << ": " << s3 << endl; +} + +int main() +{ + //test1(); + //test2(); + //test3(); + //test4(); + test5(); + + return 0; +} \ No newline at end of file diff --git a/Windows_String/String.hpp b/Windows_String/String.hpp new file mode 100644 index 0000000..c491233 --- /dev/null +++ b/Windows_String/String.hpp @@ -0,0 +1,572 @@ +#pragma once + +#include +#include +#include + +namespace Lenyiin +{ + // ʵһ֧ɾĵ string + class String + { + public: + // + typedef char* iterator; + typedef const char* const_iterator; + typedef char* riterator; + typedef const char* const_riterator; + + iterator begin() // ׵ַ + { + return _str; + } + + iterator end() // βַ + { + return _str + _size; + } + + const_iterator begin() const + { + return _str; + } + + const_iterator end() const + { + return _str + _size; + } + + riterator rbegin() + { + return _str + _size - 1; + } + + riterator rend() + { + return _str - 1; + } + + const_riterator rbegin() const + { + return _str + _size - 1; + } + + const_riterator rend() const + { + return _str - 1; + } + + public: + //// ĬϹ캯һַ + //String() + // : _str(nullptr), _size(0), _capacity(0) + //{ + //} + + //// Ĺ캯CַString + //String(const char* str) { + // if (str) { + // _size = _capacity = strlen(str); + // _str = new char[_size + 1]; // ڴ棬+1Ϊ˴洢ֹ'\0' + // strcpy(_str, str); // ַݸƵdataָڴ + // } + // else { + // _str = nullptr; + // _size = _capacity = 0; + // } + //} + + // д + // ĬϹ캯 + String(const char* str = "") // ĬϹ캯 + : _str(new char[strlen(str) + 1]), _size(strlen(str)), _capacity(_size) + { + strcpy(_str, str); + } + + // 캯 + //String(const String& s) // 캯 + // : _str(new char[s._capacity + 1]), _size(s._size), _capacity(s._capacity) + //{ + // strcpy(_str, s._str); + //} + + // д + // ĬϹ + String(const String& s) + : String(s._str) + {} + + // ֵ + //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); + } + + String& operator=(String s) + { + this->Swap(s); + + return *this; + } + + String& operator=(const char* str) + { + String s(str); + this->Swap(s); + + return *this; + } + + // ƶ캯 + String(String&& s) noexcept + : _str(s._str), _size(s._size), _capacity(s._capacity) + { + s._str = nullptr; + s._size = s._capacity = 0; + } + + // ƶֵ + String& operator=(String&& s) noexcept + { + if (this != &s) { + delete[] _str; // ͷŵǰڴ + + _str = s._str; // ӹԴ + _size = s._size; + _capacity = s._capacity; + + s._str = nullptr; // otherΪĬ״̬ + s._size = s._capacity = 0; + } + + return *this; + } + + // [] + char& operator[](size_t pos) + { + assert(pos < _size); + + return _str[pos]; + } + + const char& operator[](size_t pos) const + { + assert(pos < _size); + + return _str[pos]; + } + + // ȡ˽гԱ + size_t size() const // ȡЧַ + { + return _size; + } + + size_t capacity() const // ȡЧ + { + return _capacity; + } + + const char* c_str() const // ַ + { + return _str; + } + + // + ~String() + { + delete[] _str; + _str = nullptr; + _size = _capacity = 0; + } + + // ٿռ + void reserve(size_t newcapacity) + { + if (newcapacity > _capacity) + { + char* newstr = new char[newcapacity + 1]; + strcpy(newstr, _str); + delete[] _str; + _str = newstr; + _capacity = newcapacity; + } + } + + // ָС, ʼ + void resize(size_t newsize, char ch = '\0') + { + if (newsize < _size) + { + _size = newsize; + _str[_size] = '\0'; + } + else + { + if (newsize > _capacity) + { + reserve(newsize); + } + for (size_t i = _size; i < newsize; i++) + { + _str[i] = ch; + } + _size = newsize; + _str[_size] = '\0'; + } + } + + // β + void push_back(char ch) // βһַ + { + if (_size == _capacity) + { + size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2; + reserve(newcapacity); + } + + _str[_size++] = ch; + _str[_size] = '\0'; + } + + // ׷ + void append(const char ch) + { + push_back(ch); + } + + void append(const char* str) // ׷һַ + { + size_t len = strlen(str); + if (_size + len > _capacity) + { + reserve(_size + len); + } + + strcpy(_str + _size, str); + _size += len; + } + + void append(const String& s) // ׷һ + { + append(s._str); + } + + // += + String& operator+=(const char ch) + { + this->push_back(ch); + + return *this; + } + + String& operator+=(const char* str) + { + this->append(str); + + return *this; + } + + String& operator+=(const String& s) + { + append(s); + + return *this; + } + + // λòַ + String& insert(size_t pos, char ch) + { + assert(pos <= _size); + + if (_size == _capacity) + { + size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2; + reserve(newcapacity); + } + + int end = _size; + while (end >= (int)pos) + { + _str[end + 1] = _str[end]; + --end; + } + _str[pos] = ch; + ++_size; + + return *this; + } + + // λòַ + String& insert(size_t pos, const char* str) + { + assert(pos <= _size); + + // 1. ռ䲻 + size_t len = strlen(str); + if (_size + len > _capacity) + { + reserve(_size + len); + } + + // 2. Ų + int end = _size; + while (end >= (int)pos) + { + _str[end + len] = _str[end]; + --end; + } + + // 3. + strncpy(_str + pos, str, len); + _size += len; + + return *this; + } + + // λòһ + String& insert(size_t pos, const String& s) + { + return insert(pos, s._str); + } + + // ɾ + String& erase(size_t pos = 0, size_t len = npos) + { + assert(pos < _size); + + if (len >= _size - pos) + { + _str[pos] = '\0'; + _size = pos; + } + else + { + while (pos <= _size - len) + { + _str[pos] = _str[pos + len]; + ++pos; + } + _size -= len; + } + + return *this; + } + + // βɾ + void pop_back() + { + assert(_size > 0); + + --_size; + _str[_size] = '\0'; + } + + // < + bool operator<(const String& s) + { + int ret = strcmp(_str, s._str); + + return ret < 0; + } + + // == + bool operator==(const String& s) + { + int ret = strcmp(_str, s._str); + + return ret == 0; + } + + // <= + bool operator<=(const String& s) + { + return *this < s || *this == s; + } + + // > + bool operator>(const String& s) + { + int ret = strcmp(_str, s._str); + + return ret > 0; + } + + // >= + bool operator>=(const String& s) + { + return !(*this < s); + } + + // != + bool operator!=(const String& s) + { + return !(*this == s); + } + + // ַ + 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; + } + + // ַ + size_t find(const char* str, size_t pos = 0) const + { + char* p = strstr(_str, str); + + if (p == nullptr) + { + return npos; + } + else + { + return p - _str; + } + } + + // Ҷ + size_t find(const String& s, size_t pos = 0) const + { + return find(s._str, pos); + } + + // ַ + size_t rfind(char ch, size_t pos = npos) const + { + if (pos == npos) + { + pos = _size - 1; + } + + for (int i = pos; i >= 0; i--) + { + if (_str[i] == ch) + { + return i; + } + } + + return npos; + } + + // ַ + size_t rfind(const char* str, size_t pos = npos) + { + size_t len = strlen(str); + if (len > _size) + { + return npos; + } + + if (pos >= _size) + { + pos = _size - 1; + } + + for (size_t i = pos; i != npos; i--) + { + if (strncmp(_str + i, str, len) == 0) + { + return i; + } + } + + return npos; + } + + String substr(size_t pos = 0, size_t len = npos) const + { + assert(pos < _size); + + if (len == npos || len + pos > _size) + { + len = _size - pos; + } + + char* buffer = new char[len + 1]; + strncpy(buffer, _str + pos, len); + buffer[len] = '\0'; + + return String(buffer); + + } + + // + void clear() + { + _size = 0; + _str[_size] = '\0'; + } + + private: + char* _str; + size_t _size; // ¼Ѿ洢˶Чַ + size_t _capacity; // ¼ܴ洢Чַ '\0' β ΪЧַ + + public: + static size_t npos; // size_t -> unsigned long long -1 һ + }; + + size_t String::npos = -1; + + std::ostream& operator<<(std::ostream& _cout, const String& s) + { + for (size_t i = 0; i < s.size(); i++) + { + _cout << s[i]; + } + return _cout; + } + + std::istream& operator>>(std::istream& _cin, String& s) + { + while (true) + { + char ch; + //_cin >> ch; + ch = _cin.get(); + + //if (ch == '\n') // ͨзָ + if (ch == ' ' || ch == '\n') + { + break; + } + else + { + s += ch; + } + } + + return _cin; + } +} \ No newline at end of file diff --git a/Windows_String/Windows_String.sln b/Windows_String/Windows_String.sln new file mode 100644 index 0000000..feab7af --- /dev/null +++ b/Windows_String/Windows_String.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.7.34221.43 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Windows_String", "Windows_String.vcxproj", "{11DD664B-36CD-416E-85E2-DFB38F3EA5C9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {11DD664B-36CD-416E-85E2-DFB38F3EA5C9}.Debug|x64.ActiveCfg = Debug|x64 + {11DD664B-36CD-416E-85E2-DFB38F3EA5C9}.Debug|x64.Build.0 = Debug|x64 + {11DD664B-36CD-416E-85E2-DFB38F3EA5C9}.Debug|x86.ActiveCfg = Debug|Win32 + {11DD664B-36CD-416E-85E2-DFB38F3EA5C9}.Debug|x86.Build.0 = Debug|Win32 + {11DD664B-36CD-416E-85E2-DFB38F3EA5C9}.Release|x64.ActiveCfg = Release|x64 + {11DD664B-36CD-416E-85E2-DFB38F3EA5C9}.Release|x64.Build.0 = Release|x64 + {11DD664B-36CD-416E-85E2-DFB38F3EA5C9}.Release|x86.ActiveCfg = Release|Win32 + {11DD664B-36CD-416E-85E2-DFB38F3EA5C9}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {92B12DA5-3E85-4A89-B42E-9126D6A3BBC6} + EndGlobalSection +EndGlobal diff --git a/Windows_String/Windows_String.vcxproj b/Windows_String/Windows_String.vcxproj new file mode 100644 index 0000000..39cc026 --- /dev/null +++ b/Windows_String/Windows_String.vcxproj @@ -0,0 +1,138 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {11dd664b-36cd-416e-85e2-dfb38f3ea5c9} + WindowsString + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/Windows_String/Windows_String.vcxproj.filters b/Windows_String/Windows_String.vcxproj.filters new file mode 100644 index 0000000..34c4299 --- /dev/null +++ b/Windows_String/Windows_String.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 头文件 + + + + + 源文件 + + + \ No newline at end of file diff --git a/Windows_String/Windows_String.vcxproj.user b/Windows_String/Windows_String.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/Windows_String/Windows_String.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Windows_String/x64/Debug/String.obj b/Windows_String/x64/Debug/String.obj new file mode 100644 index 0000000..b4f7f34 Binary files /dev/null and b/Windows_String/x64/Debug/String.obj differ diff --git a/Windows_String/x64/Debug/Windows_String.exe b/Windows_String/x64/Debug/Windows_String.exe new file mode 100644 index 0000000..cfc861f Binary files /dev/null and b/Windows_String/x64/Debug/Windows_String.exe differ diff --git a/Windows_String/x64/Debug/Windows_String.exe.recipe b/Windows_String/x64/Debug/Windows_String.exe.recipe new file mode 100644 index 0000000..e2f72b5 --- /dev/null +++ b/Windows_String/x64/Debug/Windows_String.exe.recipe @@ -0,0 +1,11 @@ + + + + + E:\Git 仓库\公开仓库\3_String\Windows_String\x64\Debug\Windows_String.exe + + + + + + \ No newline at end of file diff --git a/Windows_String/x64/Debug/Windows_String.ilk b/Windows_String/x64/Debug/Windows_String.ilk new file mode 100644 index 0000000..1f19a6a Binary files /dev/null and b/Windows_String/x64/Debug/Windows_String.ilk differ diff --git a/Windows_String/x64/Debug/Windows_String.log b/Windows_String/x64/Debug/Windows_String.log new file mode 100644 index 0000000..e51b1b9 --- /dev/null +++ b/Windows_String/x64/Debug/Windows_String.log @@ -0,0 +1,5 @@ + String.cpp +E:\Git 仓库\公开仓库\3_String\Windows_String\String.hpp(309,12): warning C4267: “初始化”: 从“size_t”转换到“int”,可能丢失数据 +E:\Git 仓库\公开仓库\3_String\Windows_String\String.hpp(334,12): warning C4267: “初始化”: 从“size_t”转换到“int”,可能丢失数据 +E:\Git 仓库\公开仓库\3_String\Windows_String\String.hpp(471,15): warning C4267: “初始化”: 从“size_t”转换到“int”,可能丢失数据 + Windows_String.vcxproj -> E:\Git 仓库\公开仓库\3_String\Windows_String\x64\Debug\Windows_String.exe diff --git a/Windows_String/x64/Debug/Windows_String.pdb b/Windows_String/x64/Debug/Windows_String.pdb new file mode 100644 index 0000000..73ad675 Binary files /dev/null and b/Windows_String/x64/Debug/Windows_String.pdb differ diff --git a/Windows_String/x64/Debug/Windows_String.tlog/CL.command.1.tlog b/Windows_String/x64/Debug/Windows_String.tlog/CL.command.1.tlog new file mode 100644 index 0000000..61fa5ff Binary files /dev/null and b/Windows_String/x64/Debug/Windows_String.tlog/CL.command.1.tlog differ diff --git a/Windows_String/x64/Debug/Windows_String.tlog/CL.read.1.tlog b/Windows_String/x64/Debug/Windows_String.tlog/CL.read.1.tlog new file mode 100644 index 0000000..71f7dd1 Binary files /dev/null and b/Windows_String/x64/Debug/Windows_String.tlog/CL.read.1.tlog differ diff --git a/Windows_String/x64/Debug/Windows_String.tlog/CL.write.1.tlog b/Windows_String/x64/Debug/Windows_String.tlog/CL.write.1.tlog new file mode 100644 index 0000000..764a192 Binary files /dev/null and b/Windows_String/x64/Debug/Windows_String.tlog/CL.write.1.tlog differ diff --git a/Windows_String/x64/Debug/Windows_String.tlog/Cl.items.tlog b/Windows_String/x64/Debug/Windows_String.tlog/Cl.items.tlog new file mode 100644 index 0000000..da58323 --- /dev/null +++ b/Windows_String/x64/Debug/Windows_String.tlog/Cl.items.tlog @@ -0,0 +1 @@ +E:\Git 仓库\公开仓库\3_String\Windows_String\String.cpp;E:\Git 仓库\公开仓库\3_String\Windows_String\x64\Debug\String.obj diff --git a/Windows_String/x64/Debug/Windows_String.tlog/Windows_String.lastbuildstate b/Windows_String/x64/Debug/Windows_String.tlog/Windows_String.lastbuildstate new file mode 100644 index 0000000..2db0f4a --- /dev/null +++ b/Windows_String/x64/Debug/Windows_String.tlog/Windows_String.lastbuildstate @@ -0,0 +1,2 @@ +PlatformToolSet=v143:VCToolArchitecture=Native64Bit:VCToolsVersion=14.37.32822:TargetPlatformVersion=10.0.22000.0: +Debug|x64|E:\Git 仓库\公开仓库\3_String\Windows_String\| diff --git a/Windows_String/x64/Debug/Windows_String.tlog/link.command.1.tlog b/Windows_String/x64/Debug/Windows_String.tlog/link.command.1.tlog new file mode 100644 index 0000000..d95747f Binary files /dev/null and b/Windows_String/x64/Debug/Windows_String.tlog/link.command.1.tlog differ diff --git a/Windows_String/x64/Debug/Windows_String.tlog/link.read.1.tlog b/Windows_String/x64/Debug/Windows_String.tlog/link.read.1.tlog new file mode 100644 index 0000000..02277aa Binary files /dev/null and b/Windows_String/x64/Debug/Windows_String.tlog/link.read.1.tlog differ diff --git a/Windows_String/x64/Debug/Windows_String.tlog/link.write.1.tlog b/Windows_String/x64/Debug/Windows_String.tlog/link.write.1.tlog new file mode 100644 index 0000000..9ba800b Binary files /dev/null and b/Windows_String/x64/Debug/Windows_String.tlog/link.write.1.tlog differ diff --git a/Windows_String/x64/Debug/Windows_String.vcxproj.FileListAbsolute.txt b/Windows_String/x64/Debug/Windows_String.vcxproj.FileListAbsolute.txt new file mode 100644 index 0000000..9c79213 --- /dev/null +++ b/Windows_String/x64/Debug/Windows_String.vcxproj.FileListAbsolute.txt @@ -0,0 +1 @@ +E:\Git 仓库\公开仓库\3_String\Windows_String\x64\Debug\Windows_String.exe diff --git a/Windows_String/x64/Debug/vc143.idb b/Windows_String/x64/Debug/vc143.idb new file mode 100644 index 0000000..179f43f Binary files /dev/null and b/Windows_String/x64/Debug/vc143.idb differ diff --git a/Windows_String/x64/Debug/vc143.pdb b/Windows_String/x64/Debug/vc143.pdb new file mode 100644 index 0000000..16c5f42 Binary files /dev/null and b/Windows_String/x64/Debug/vc143.pdb differ