diff --git a/pure-c-test/20220407/3-7.c b/pure-c-test/20220407/3-7.c new file mode 100644 index 0000000..e69de29 diff --git a/pure-c-test/20220407/3-8.c b/pure-c-test/20220407/3-8.c new file mode 100644 index 0000000..e69de29 diff --git a/work20220401/.idea/encodings.xml b/work20220401/.idea/encodings.xml new file mode 100644 index 0000000..674fa4b --- /dev/null +++ b/work20220401/.idea/encodings.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/work20220401/neoString/CString.cpp b/work20220401/neoString/CString.cpp index 00811e4..0012836 100644 --- a/work20220401/neoString/CString.cpp +++ b/work20220401/neoString/CString.cpp @@ -22,7 +22,7 @@ CString::CString() : CString(512) {} /** * 从源中复制字符串来构建新的对象 */ -CString::CString(char *source) : CString(source, (int) strlen(source)) {} +CString::CString(const char *source) : CString(source, (int) strlen(source)) {} /** * 从源中复制字符串来构建新的对象,并定义初始长度,小于源字符串则会被截取 diff --git a/work20220401/neoString/CString.h b/work20220401/neoString/CString.h index 9c40504..bad35d6 100644 --- a/work20220401/neoString/CString.h +++ b/work20220401/neoString/CString.h @@ -24,7 +24,7 @@ public: CString(char *data, int length); - explicit CString(char *source); + explicit CString(const char *source); CString(const CString &source); diff --git a/work20220407/.idea/deployment.xml b/work20220407/.idea/deployment.xml index 771f492..7b94c79 100644 --- a/work20220407/.idea/deployment.xml +++ b/work20220407/.idea/deployment.xml @@ -1,12 +1,21 @@ - + - + + + + + + + + + + diff --git a/work20220407/.idea/other.xml b/work20220407/.idea/other.xml new file mode 100644 index 0000000..1c25a68 --- /dev/null +++ b/work20220407/.idea/other.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/work20220407/main.cpp b/work20220407/main.cpp index e571d05..feef35b 100644 --- a/work20220407/main.cpp +++ b/work20220407/main.cpp @@ -1,24 +1,26 @@ #include #include "string/String.h" +#include "utility" using namespace std; +using namespace rel_ops; // 测试示例来自题目 int main() { - String s1("Help!"),s2("Good!"),s3(s2),s4,s5; - cout<<"s1="<length = length; } +String::String(const String &source) : String(source.data, source.length) {} + String::~String() { delete[] data; data = nullptr; } -String::String(const String &source) : String(source.data, source.length) {} - /** * 重载等号,其实现抽象为equals函数 - * @param source - * @return */ bool String::operator==(const String &source) const { return equals(source.data, source.length); @@ -55,7 +57,7 @@ bool String::operator==(const char *source) const { } /** - * 借鉴了Java中String类的equal()方法的实现思路。 + * 字符串判等 * 首先判断data是否为nullptr,同为null则true,否则就是false * 再比较两字符串长度,如果长度不一样不用说,直接返回false; * 相同的话再比较两字符串数据指针指向地址是否一样,一样就代表指向的是同一块内存,直接返回true @@ -80,6 +82,9 @@ bool String::equals(const char *source, int sourceLength) const { return strcmp(this->data, source) == 0; } +/* + * 重载等号运算符,具体实现为copyData()函数 + */ String &String::operator=(const String &source) { if (this == &source) { return *this; @@ -161,9 +166,9 @@ void String::addString(const char *source, int sourceLength) { strcpy(old, data); // 重新分配内存,防止拼接后溢出 - // 分配两倍内存空间来减少重新分配次数 - delete[] data; + // 分配两倍内存空间来减少重新分配次数(空间换时间?) allocSize = (length + sourceLength)*2 + 1; + delete[] data; this->data = new char[allocSize](); strcpy(data, old); @@ -196,20 +201,30 @@ std::ostream &operator<<(std::ostream &outputStream, const String &source) { } std::istream &operator>>(std::istream &inputStream, String &source) { - // 使用istream.get(char*, int)可以限制读入的长度,防止输入超长的字符串导致溢出,但是空格也会被读入 - // 手动分割太麻烦,因此只好先用这种方法了 - inputStream >> source.data; - source.length = (int) strlen(source.data); + // 其实这里有个问题,如果用户的输入超过了4028个字符,会导致溢出,不安全 + // 虽然可以像std::string那样分批读入,动态分配,这样过长就不会被截掉, + // 但是为了简单起见,在这里就直接>>了 + char* input = new char[4028](); + if (std::cin >> input) { + strncpy(source.data, input, source.allocSize - 1); + + int inputLength = (int) strlen(input); + source.length = (int) std::min(inputLength, source.allocSize - 1); + + source.data[source.length] = '\0'; + } return inputStream; } char &String::operator[](int i) { - return (i < length && i >= 0) ? data[i] : data[0]; + // 用断言处理下标越界,一般应该用异常处理,但是简单起见还是断言吧 + assert(i < length); + return data[i]; } /** - * 加号运算重载,注意,每次加号运算都会产生一个新的对象 + * 加号运算重载,每次加号运算都会产生一个新的对象 * 这里不用引用返回是因为返回局部对象不是安全的 */ String String::operator+(const char *source) { @@ -232,4 +247,4 @@ String String::operator+(const String &source) { int String::Length() const { return length; -} +} \ No newline at end of file