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="<>s4;
- cout<<"s4="<> s4;
+ cout << "s4=" << s4 << endl;
+ s5 = s3 + s4;
+ cout << "s5=" << s5 << endl;
+ s5[5] = 'g';
+ cout << "s5=" << s5 << endl;
+ cout << "strlen(s5)=" << s5.Length() << endl;
+ cout << boolalpha << (s3 == s1) << endl;
+}
diff --git a/work20220407/string/String.cpp b/work20220407/string/String.cpp
index 6170991..49303c2 100644
--- a/work20220407/string/String.cpp
+++ b/work20220407/string/String.cpp
@@ -4,8 +4,12 @@
#include
#include
+#include
#include "String.h"
+#include "utility"
+
+using namespace std::rel_ops;
/**
* 按照给定大小来初始化空的字符串数据
@@ -15,7 +19,7 @@ String::String(int size) : length(0), allocSize(size) {
}
/**
- * 不设定初始化大小就默认128个字符来初始化
+ * 不设定初始化大小就默认128个字符空间来初始化
*/
String::String() : String(128) {}
@@ -34,17 +38,15 @@ String::String(const char *source, int length) : String(length + 1) {
this->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