我必须使用运算符[],+,+ =,<<,>>,==,!=,<,< =,>,> =来实现字符串类,但是我不能使用字符串对象或包含c ++库。到目前为止,这是我的代码:
# define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstring>
#include<fstream>
using namespace std;
class MyString {
public:
MyString();
MyString(const char* chars);
int length() const;
char * getValue()const;
~MyString();
//copy constructor
MyString(const MyString&);
MyString& operator =(const MyString& s);
char& operator[](int i);
MyString& operator+=(const MyString& s);
friend ostream& operator<<(ostream&os, const MyString&s);
friend istream& operator >> (istream&is, MyString&s);
friend bool operator ==(const MyString& s1, const MyString& s2);
friend bool operator <(const MyString& s1, const MyString& s2);
private:
char* value;
int size;
};
MyString operator+(const MyString s1, const MyString& s2);
bool operator !=(const MyString& s1, const MyString& s2);
bool operator >=(const MyString& s1, const MyString& s2);
bool operator <=(const MyString& s1, const MyString& s2);
bool operator > (const MyString& s1, const MyString& s2);
//no arguments constructor
MyString::MyString() {
value = 0;
size = 0;
}
//constructor
MyString::MyString(const char* chars) {
size = strlen(chars);
value = new char[size + 1];
strcpy(value, chars);
}
int MyString::length()const {
return size;
}
char* MyString::getValue()const {
return value;
}
MyString::~MyString() {
delete[] value;
}
//copy constructor
MyString::MyString(const MyString& s) {
size = s.size;
value = new char[size + 1];
strcpy(value, s.value);
}
MyString& MyString::operator=(const MyString&s) {
if (s.value == 0) {
delete[] value;
value = 0;
size = 0;
return *this;
}
if (this != &s) {
delete[] value;
value = new char[s.size + 1];
strcpy(value, s.value);
size = s.size;
}
return *this;
}
char& MyString::operator[](int i) {
if (i < 0 || i >= size) {
cout << "Please enter correct value of index" << endl;
exit(0);
}
else {
return value[i];
}
return value[i];
}
MyString& MyString::operator+=(const MyString& s) {
char** temp = &value;
*temp = new char[size];
strcpy(value,*temp);
strcat(value, s.getValue());
if (size != 0) {
delete[] temp;
}
size = strlen(value);
return *this;
}
ostream& operator<<(ostream&out, const MyString&s) {
out << s.value;
return out;
}
istream& operator >> (istream&in, MyString&s) {
char*ptr = new char[100];
in >> ptr;
s = MyString(ptr);
delete ptr;
return in;
}
MyString operator+(const MyString s1, const MyString& s2) {
MyString answer;
answer += s1;
answer+= s2;
return answer;
}
bool operator ==(const MyString&s1, const MyString& s2) {
return(strcmp(s1.value, s2.value) == 0);
}
bool operator<(const MyString& s1, const MyString& s2) {
return (strcmp(s1.value, s2.value) < 0);
}
bool operator !=(const MyString& s1, const MyString& s2) {
return !(s1 == s2);
}
bool operator>(const MyString& s1, const MyString& s2) {
return !(s1 == s2) && !(s1 < s2);
}
bool operator<=(const MyString& s1, const MyString& s2) {
return s1 < s2 || s1 == s2;
}
bool operator >=(const MyString & s1, const MyString& s2) {
return !(s1 < s2);
}
void test_copy_and_destructor(MyString S) {
cout << "test: copy constructor and destructor calls: " << endl;
MyString temp = S;
cout << "temp inside function test_copy_and_destructor: " << temp << endl;
}
int main() {
MyString st1("abc abc");
MyString st2("9fgth");
cout << "Copy constructor , << operator" << endl;
MyString st3(st1);
cout << "st3: " << st3 << endl;
test_copy_and_destructor(st2);
MyString st4;
cout << "operator + " << endl;
st4 = st3 + st2;
cout << "st4: " << st4 << endl;
cout << "st1 + st2: " << (st1 + st2) << endl;
cout << "operators [ ] " << endl;
for (int i = 0; i < st2.length(); i++)
cout << st2[i] << " ";
cout << endl;
cout << "operators += , ==, != " << endl;
st2 += st1;
if (st3 == st1)
cout << "st3 and st1 are identical " << endl;
else cout << "st3 and st1 are not identical " << endl;
if (st2 != st1)
cout << "st2 and st1 are not identical " << endl;
else cout << "st2 and st1 are identical " << endl;
cout << "operators < , <=, >, >= " << endl;
if (st2 < st1)
cout << "st2 < st1 " << endl;
else cout << "st2 is not less than st1 " << endl;
if (st1 <= st2)
cout << "st1 <= st2 " << endl;
else cout << "st1 is not less than or equal to st2 " << endl;
if (st1 > st2)
cout << "st1 > st2 " << endl;
else cout << "not (st1 > st2) " << endl;
if (st1 >= st2)
cout << "st1 >= st2 " << endl;
else cout << "not (st1 >= st2) " << endl;
cout << "operator >> " << endl;
//Open the data file
ifstream input("A9_input.txt");
if (input.fail()) {
cout << "unable to open input file A9_input.txt, Exiting..... ";
return 0;
}
MyString temp1;
MyString temp2("aaa");
input >> temp1;
input >> temp2;
cout << "first element of input file: " << temp1 << endl;
cout << "second element of input file: " << temp2 << endl;
input.close();
cout << "MyString says farewell....." << endl;
return 0;
}
到达操作员+我的代码到达断点并崩溃。我可以告诉我的+ =运算符代码有问题,因为+正在使用+ =代码。有人可以帮我弄清楚我的+ =代码有什么问题吗?
答案 0 :(得分:0)
你的问题是你试图改变指针所指向的指针,而不是指向指针的指针。 当你使用new运算符时,你的指针只是在堆上得到新的地址,而你之前做的赋值(char * temp = value)是irelvent。 因为临时地址上的任何修改都不会影响价值,因此临时地址获取地址由价值而不是价值地址。 你真正想做的是:
char ** temp = &value;//now temp holds value's address.
*temp = new char[size];
//modify temp will modify value, but you need to derefrence before each use.
你也可以这样做:
char * temp = new char[size];
//strcpy_s(dest, length of dest, src)
strcpy_s(temp , sizeof temp, value);//copy value to temp
strcat_s(temp, sizeof temp, s.getValue());
if(value != nullptr)
delete [] value;
value = temp;
<强>更新强>
你试图将一个更大的字符串temp复制到值中,这会导致溢出(这是一个使用strcpy_s / strcat_s的好习惯,因为它们不能复制超过你给它们的长度,这应该是dest的大小)。
链接到strcpy / strcpy_s doc: http://en.cppreference.com/w/c/string/byte/strcpy http://en.cppreference.com/w/c/string/byte/strcat
你应该做的是:
${jobs.value}
答案 1 :(得分:0)
问题是您使用strcpy()
和strcat()
填充旧分配,这个分配不够大。因此,strcat()
调用尝试写入此分配的结尾,结果是未定义的行为,这表现为系统崩溃。
char* temp = value;
temp = new char[strlen(value) + s.length() +1];
strcpy(value, temp); // <-- should be copying the other way
strcat(value, s.getValue()); // <-- should be copying into temp, not value
//if (size != 0) {
// delete[]temp;
//}
size = strlen(value);
return *this;
重写以解决此问题,并释放原始字符串,并检查value == nullptr
:
char *oldString = value == nullptr ? "" : value;
int newSize = strlen(oldString) + s.length();
char *newString = new char[newSize + 1];
strcpy(newString, oldString);
strcat(newString, s.getValue());
delete [] value;
value = newString;
size = newSize;
return *this;