改了一下动态分配的版本,不过还是有一点问题

main
lensfrex 3 years ago
parent 39f8b9a333
commit ef831c6a0e
Signed by: lensfrex
GPG Key ID: 0F69A0A2FBEE98A0
  1. 144
      work20220401/neoString/CString.cpp
  2. 18
      work20220401/neoString/CString.h

@ -7,36 +7,41 @@
#include "CString.h" #include "CString.h"
/* /**
* *
*/ */
CString::CString(int size) { CString::CString(int size) : length(0), allocSize(size) {
data = new char[size](); data = new char[size]();
} }
CString::~CString() { /**
delete[] data; * 512
data = nullptr; */
} CString::CString() : CString(512) {}
/* /**
* 5120... *
*/ */
CString::CString() : CString(MAX_LENGTH) {} CString::CString(char *source) : CString(source, (int) strlen(source)) {}
/* /**
* MAX_LENGTH的部分不会被放入 *
*/ */
CString::CString(char *source) : CString(MAX_LENGTH) { CString::CString(char *source, int length) : CString(length + 1) {
strncpy(data, source, MAX_LENGTH); strncpy(data, source, length);
data[length] = '\0';
int sourceLength = (int) strlen(source); this->length = length;
if (sourceLength < MAX_LENGTH) {
data[sourceLength] = 0;
}
} }
/* CString::~CString() {
delete[] data;
data = nullptr;
}
CString::CString(const CString &source) : CString(source.data) {}
/**
* Java中String类的equal() * Java中String类的equal()
* data是否为nullptrnull则truefalse * data是否为nullptrnull则truefalse
* false * false
@ -49,11 +54,8 @@ bool CString::operator==(const CString &source) const {
return source.data == nullptr && this->data == nullptr; return source.data == nullptr && this->data == nullptr;
} }
int length = (int) strlen(data);
int sourceLength = (int) strlen(source.data);
// 字符串长度不等,字符串肯定是不等 // 字符串长度不等,字符串肯定是不等
if (length != sourceLength) { if (length != source.length) {
return false; return false;
} else { } else {
// 长度相等且data指向相同肯定等 // 长度相等且data指向相同肯定等
@ -63,8 +65,8 @@ bool CString::operator==(const CString &source) const {
} }
// 以上情况都不符合时才进行逐字比较 // 以上情况都不符合时才进行逐字比较
int compareLength = std::min(sourceLength, length); // 能执行到此处两者长度肯定相等,因此访问数组不会越界
for (int i = 0; i < compareLength; ++i) { for (int i = 0; i < length; ++i) {
if (data[i] != source.data[i]) { if (data[i] != source.data[i]) {
return false; return false;
} }
@ -82,22 +84,25 @@ CString &CString::operator=(const CString &source) {
if (source.data == nullptr) { if (source.data == nullptr) {
delete[] data; delete[] data;
this->data = nullptr; this->data = nullptr;
length = 0;
allocSize = 0;
return *this; return *this;
} }
// 如果本来是null的话就先分配好空间 int sourceLength = (int) strlen(source.data);
if (this->data == nullptr) {
this->data = new char[MAX_LENGTH]();
}
strncpy(data, source.data, MAX_LENGTH); // 如果源字符串长度超过了本对象已分配的字符数组大小则重新分配长度合适的字符数组
if (allocSize < sourceLength) {
allocSize = sourceLength + 1;
int sourceLength = (int) strlen(source.data); delete[] data;
if (sourceLength < MAX_LENGTH) { data = new char[allocSize];
data[sourceLength] = 0;
} }
strcpy(data, source.data);
length = sourceLength;
return *this; return *this;
} }
@ -107,47 +112,74 @@ CString &CString::operator+=(const CString &source) {
return *this; return *this;
} }
int sourceLength = (int) strlen(source.data); // 本对象nullptr的话就直接新分配
int length = 0;
// 本对象nullptr的话就先新分配再拼接
if (data == nullptr) { if (data == nullptr) {
this->data = new char[MAX_LENGTH](); allocSize = source.length + 2 + 1;
length = sourceLength; this->data = new char[allocSize]();
length = source.length;
} else { } else {
length = (int) strlen(data); length = (int) strlen(data);
} }
// 先加两个横杠... // 如果拼接后字符长度超过已分配的内存大小,则重新分配data内存大小
for (int i = length, j = 0; i < MAX_LENGTH && j < 2; ++i, ++j) { if (allocSize < (length + source.length + 2)) {
this->data[i] = '-'; // 保存拼接前的原数据,以便重新分配足够的内存
} char *old = new char[length + 1]();
// 去他的strcat,不判溢出什么的了,直接手动实现判断 strcpy(old, data);
for (int i = length + 2, j = 0; i < MAX_LENGTH && j < sourceLength; ++i, ++j) {
this->data[i] = source.data[j]; // 重新分配内存,防止拼接后溢出,2为两个横杠大小
length += source.length + 2;
allocSize = length + 1;
delete[] data;
this->data = new char[allocSize]();
strcpy(data, old);
} }
strcat(data, "--");
strcat(data, source.data);
return *this; return *this;
} }
CString::CString(const CString &source) : CString(source.data) {} /**
/*
* *
*/ */
bool CString::operator>(const CString &source) const { bool CString::operator>(const CString &compareString) const {
// 管他data空不空呢,不是这里该管的事,调用方在调用前就应该判断了 // 首先判断两CString对象data成员是否为空指针,空直接返回false
return strcoll(this->data, source.data) > 0; if (compareString.data == nullptr || this->data == nullptr) {
return false;
}
// 两对象data成员首指向相同则对比谁长
if (compareString.data == this->data) {
return length > compareString.length;
}
// 以上情况都不符合时才进行逐字比较
int compareLength = std::min(compareString.length, length);
for (int i = 0; i < compareLength; ++i) {
if (data[i] > compareString.data[i]) {
return true;
}
}
return false;
} }
std::ostream &operator<<(std::ostream &outputStream, const CString &source) { std::ostream &operator<<(std::ostream &outputStream, const CString &source) {
return outputStream << source.data; return outputStream << source.data;
} }
std::istream &operator>>(std::istream &inputStream, const CString &source) { std::istream &operator>>(std::istream &inputStream, CString &source) {
return inputStream >> source.data; inputStream >> source.data;
source.length = (int) strlen(source.data);
return inputStream;
} }
char CString::operator[](const int i) const { char CString::operator[](int i) {
return (i < MAX_LENGTH) ? data[i] : '\0'; return (i < length && i >= 0) ? data[i] : '\0';
} }

@ -9,15 +9,20 @@
#include "utility" #include "utility"
using namespace std::rel_ops; using namespace std::rel_ops;
class CString { class CString {
private: private:
// 字符数组做字符串
char *data = nullptr; char *data = nullptr;
explicit CString(int size); // 字符串实际长度
int length = 0;
// 已分配的字符数量
int allocSize = 0;
public: public:
const static int MAX_LENGTH = 5120; explicit CString(int size);
CString(char *data, int length);
explicit CString(char *source); explicit CString(char *source);
@ -29,17 +34,16 @@ public:
bool operator==(const CString &source) const; bool operator==(const CString &source) const;
bool operator>(const CString &source) const; bool operator>(const CString &compareString) const;
char operator[](int i) const;
CString &operator+=(const CString &source); CString &operator+=(const CString &source);
CString &operator=(const CString &source); CString &operator=(const CString &source);
friend std::ostream &operator<<(std::ostream &outputStream, const CString &source); friend std::ostream &operator<<(std::ostream &outputStream, const CString &source);
friend std::istream &operator>>(std::istream &outputStream, CString &source);
friend std::istream &operator>>(std::istream &outputStream, const CString &source); char operator[](int i);
}; };
#endif //WORK20220401_CSTRING_H #endif //WORK20220401_CSTRING_H
Loading…
Cancel
Save