From 589f674f02edb6ecb0b691a46bd0e8133ac3deac Mon Sep 17 00:00:00 2001 From: lensferno Date: Tue, 5 Apr 2022 15:01:22 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8E=BB=E4=BB=96=E7=9A=84=E5=8A=A8=E6=80=81?= =?UTF-8?q?=E5=86=85=E5=AD=98=E5=88=86=E9=85=8D=EF=BC=8C=E7=9B=B4=E6=8E=A5?= =?UTF-8?q?=E5=A4=A7=E6=89=8B=E7=AC=94=E5=88=86=E4=B8=AA5120=E5=AD=97?= =?UTF-8?q?=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- work20220401/main.cpp | 6 +- work20220401/neoString/CString.cpp | 116 ++++++++++++----------------- work20220401/neoString/CString.h | 11 ++- 3 files changed, 60 insertions(+), 73 deletions(-) diff --git a/work20220401/main.cpp b/work20220401/main.cpp index 8c8e55b..cc3cc2f 100644 --- a/work20220401/main.cpp +++ b/work20220401/main.cpp @@ -5,9 +5,9 @@ using namespace std; int main() { -// char *p = new char[15](); -// strncpy(p, "asdf", 4); -// cout << p; +// strcpy(p, "ac"); +// cout << p << endl; + int n, i, j; while (cin >> n) { CString *c = new CString[n + 2]; diff --git a/work20220401/neoString/CString.cpp b/work20220401/neoString/CString.cpp index 45408af..fe4327e 100644 --- a/work20220401/neoString/CString.cpp +++ b/work20220401/neoString/CString.cpp @@ -10,8 +10,8 @@ /* * 按照给定大小来初始化字符串数据 */ -CString::CString(int length) { - data = new char[length](); +CString::CString(int size) { + data = new char[size](); } CString::~CString() { @@ -20,9 +20,21 @@ CString::~CString() { } /* - * 不设定初始化大小就默认512个字符来初始化 + * 直接分配5120个字符... */ -CString::CString() : CString(512) {} +CString::CString() : CString(MAX_LENGTH) {} + +/* + * 从源中复制字符串来构建新的对象,超过MAX_LENGTH的部分不会被放入 + */ +CString::CString(char *source) : CString(MAX_LENGTH) { + strncpy(data, source, MAX_LENGTH); + + int sourceLength = (int) strlen(source); + if (sourceLength < MAX_LENGTH) { + data[sourceLength] = 0; + } +} /* * 重载等号。借鉴了Java中String类的equal()方法的实现思路。 @@ -37,8 +49,8 @@ bool CString::operator==(const CString &source) const { return source.data == nullptr && this->data == nullptr; } - int length = (int)strlen(data); - int sourceLength = (int)strlen(source.data); + int length = (int) strlen(data); + int sourceLength = (int) strlen(source.data); // 字符串长度不等,字符串肯定是不等 if (length != sourceLength) { @@ -60,72 +72,60 @@ bool CString::operator==(const CString &source) const { return true; } -/* - * 从源中复制字符串来构建新的对象 - */ -CString::CString(char *source) : CString((int)strlen(source)) { - strcpy(data, source); -} - -/* - * 从源中复制字符串来构建新的对象,并定义初始长度,小于源字符串则会被截取 - */ -CString::CString(char *source, int length) : CString(length) { - strncpy(data, source, length); -} - CString &CString::operator=(const CString &source) { // 处理自己给自己赋值的情况,那叫啥,自赋值 if (this == &source) { return *this; } - delete[] data; - // 等号右侧空指针的话直接data赋为空指针 - // 这里在执行前就已经delete掉data的数据了,不会泄漏 if (source.data == nullptr) { + delete[] data; this->data = nullptr; + return *this; } - int sourceLength = (int)strlen(source.data); + // 如果本来是null的话就先分配好空间 + if (this->data == nullptr) { + this->data = new char[MAX_LENGTH](); + } - this->data = new char[sourceLength](); - strcpy(data, source.data); + strncpy(data, source.data, MAX_LENGTH); + + int sourceLength = (int) strlen(source.data); + if (sourceLength < MAX_LENGTH) { + data[sourceLength] = 0; + } return *this; } CString &CString::operator+=(const CString &source) { // nullptr不做处理 - if(source.data == nullptr) { + if (source.data == nullptr) { return *this; } - int sourceLength = (int)strlen(source.data); + int sourceLength = (int) strlen(source.data); int length = 0; - // 本对象nullptr的话就直接新分配 + // 本对象nullptr的话就先新分配再拼接 if (data == nullptr) { - this->data = new char[sourceLength](); + this->data = new char[MAX_LENGTH](); length = sourceLength; } else { - length = (int)strlen(data); + length = (int) strlen(data); } - // 保存拼接前的原数据,以便重新分配足够的内存 - char *old = new char[length](); - strcpy(old, data); - - // 重新分配内存,防止拼接后溢出 - length += sourceLength; - delete[] data; - this->data = new char[length](); - - strcpy(data, old); - strcat(data, "--"); - strncat(data, source.data, sourceLength); + // 先加两个横杠... + for (int i = length, j = 0; i < MAX_LENGTH && j < 2; ++i, ++j) { + this->data[i] = '-'; + } + // 去他的strcat,不判溢出什么的了,直接手动实现判断 + for (int i = length + 2, j = 0; i < MAX_LENGTH && j < sourceLength; ++i, ++j) { + this->data[i] = source.data[j]; + } return *this; } @@ -136,30 +136,8 @@ CString::CString(const CString &source) : CString(source.data) {} * 按照字典顺序逐字对比 */ bool CString::operator>(const CString &source) const { - // 首先判断两CString对象data成员是否为空指针,空直接返回false - if (source.data == nullptr || this->data == nullptr) { - std::cout << "nullptr!"<< std::endl; - return false; - } - - int length = (int)strlen(data); - int sourceLength = (int)strlen(source.data); - - // 两对象指向data同一内存区域并且长度相等则可以判断两字符串相等,所以就不是"<" - if (sourceLength == length && source.data == this->data) { - std::cout << "memsame" << std::endl; - return false; - } - - // 以上情况都不符合时才进行逐字比较 - int compareLength = std::min(sourceLength, length); - for (int i = 0; i < compareLength; ++i) { - if (data[i] > source.data[i]) { - std::cout << "data[i]: " << data[i] << " source.data[i]: " << source.data[i] << std::endl; - return true; - } - } - return false; + // 管他data空不空呢,不是这里该管的事,调用方在调用前就应该判断了 + return strcoll(this->data, source.data) > 0; } std::ostream &operator<<(std::ostream &outputStream, const CString &source) { @@ -169,3 +147,7 @@ std::ostream &operator<<(std::ostream &outputStream, const CString &source) { std::istream &operator>>(std::istream &inputStream, const CString &source) { return inputStream >> source.data; } + +char CString::operator[](const int i) const { + return data[i]; +} \ No newline at end of file diff --git a/work20220401/neoString/CString.h b/work20220401/neoString/CString.h index 1b3bc0e..3ee2bc5 100644 --- a/work20220401/neoString/CString.h +++ b/work20220401/neoString/CString.h @@ -9,13 +9,15 @@ #include "utility" using namespace std::rel_ops; + class CString { private: char *data = nullptr; -public: - explicit CString(int length); - CString(char *data, int length); + explicit CString(int size); + +public: + const static int MAX_LENGTH = 5120; explicit CString(char *source); @@ -29,11 +31,14 @@ public: bool operator>(const CString &source) const; + char operator[](int i) const; + CString &operator+=(const CString &source); CString &operator=(const CString &source); friend std::ostream &operator<<(std::ostream &outputStream, const CString &source); + friend std::istream &operator>>(std::istream &outputStream, const CString &source); };