You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
153 lines
4.0 KiB
153 lines
4.0 KiB
//
|
|
// Created by lenfrex on 2022/4/4.
|
|
//
|
|
|
|
#include <cstring>
|
|
#include <algorithm>
|
|
|
|
#include "CString.h"
|
|
|
|
/*
|
|
* 按照给定大小来初始化字符串数据
|
|
*/
|
|
CString::CString(int size) {
|
|
data = new char[size]();
|
|
}
|
|
|
|
CString::~CString() {
|
|
delete[] data;
|
|
data = nullptr;
|
|
}
|
|
|
|
/*
|
|
* 直接分配5120个字符...
|
|
*/
|
|
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()方法的实现思路。
|
|
* 首先判断data是否为nullptr,同为null则true,否则就是false
|
|
* 再比较两字符串长度,如果长度不一样不用说,直接返回false;
|
|
* 相同的话再比较两字符串数据指针指向地址是否一样,一样就代表指向的是同一块内存,直接返回true
|
|
* 两者都不同才进行逐字比较
|
|
*/
|
|
bool CString::operator==(const CString &source) const {
|
|
// 首先判断两CString对象data成员是否为空指针
|
|
if (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) {
|
|
return false;
|
|
} else {
|
|
// 长度相等且data指向相同肯定等
|
|
if (source.data == this->data) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// 以上情况都不符合时才进行逐字比较
|
|
int compareLength = std::min(sourceLength, length);
|
|
for (int i = 0; i < compareLength; ++i) {
|
|
if (data[i] != source.data[i]) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
CString &CString::operator=(const CString &source) {
|
|
// 处理自己给自己赋值的情况,那叫啥,自赋值
|
|
if (this == &source) {
|
|
return *this;
|
|
}
|
|
|
|
// 等号右侧空指针的话直接data赋为空指针
|
|
if (source.data == nullptr) {
|
|
delete[] data;
|
|
this->data = nullptr;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// 如果本来是null的话就先分配好空间
|
|
if (this->data == nullptr) {
|
|
this->data = new char[MAX_LENGTH]();
|
|
}
|
|
|
|
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) {
|
|
return *this;
|
|
}
|
|
|
|
int sourceLength = (int) strlen(source.data);
|
|
int length = 0;
|
|
|
|
// 本对象nullptr的话就先新分配再拼接
|
|
if (data == nullptr) {
|
|
this->data = new char[MAX_LENGTH]();
|
|
length = sourceLength;
|
|
} else {
|
|
length = (int) strlen(data);
|
|
}
|
|
|
|
// 先加两个横杠...
|
|
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;
|
|
}
|
|
|
|
CString::CString(const CString &source) : CString(source.data) {}
|
|
|
|
/*
|
|
* 按照字典顺序逐字对比
|
|
*/
|
|
bool CString::operator>(const CString &source) const {
|
|
// 管他data空不空呢,不是这里该管的事,调用方在调用前就应该判断了
|
|
return strcoll(this->data, source.data) > 0;
|
|
}
|
|
|
|
std::ostream &operator<<(std::ostream &outputStream, const CString &source) {
|
|
return outputStream << source.data;
|
|
}
|
|
|
|
std::istream &operator>>(std::istream &inputStream, const CString &source) {
|
|
return inputStream >> source.data;
|
|
}
|
|
|
|
char CString::operator[](const int i) const {
|
|
return data[i];
|
|
} |