|
|
|
@ -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]; |
|
|
|
|
} |