/* string.cpp * * Note: http://msdn.microsoft.com/en-us/magazine/cc163742.aspx * */ #include "string.h" #include MyString::MyString(int len) : str_(new char[len + 1]), length_(len) { } MyString::MyString(const char *str) : length_(strlen(str)) { str_ = new char[length_ + 1]; strcpy(str_, str); } MyString::MyString(const MyString& str) : str_(new char[str.length_ + 1]), length_(str.length_) { strcpy(str_, str.str_); } MyString::~MyString() { delete[] str_; } int MyString::indexOf(char ch, int pos) const { while (pos < length_) { if (str_[pos] == ch) return pos; pos++; } return -1; } bool MyString::isSubstring(const MyString& str) const { if (length_ < str.length_) return false; int i, j, temp; for (i = 0; i < length_; i++) { j = 0; temp = i; while ((j < str.length_) && (str_[temp] == str.str_[j])) { temp++; j++; } if (j == str.length_) return true; } return false; } bool MyString::isSubstring(const char *str) const { int i, j, k; for (i = 0; i < length_; i++) { j = i; k = 0; while (str_[j++] == str[k++]) ; if (str[k-1] == '\0') return true; } return false; } /* there are few ways to implement this */ MyString& MyString::concat(const MyString& str) { /* right way to do this would be to use realloc and double the buffer each * we append something (if it's full) */ MyString ret(length_ + str.length_); strcpy(ret.str_, str_); strcat(ret.str_, str.str_); return (*this = ret); } MyString& MyString::concat(const char *str) { char *newstr = new char[length_ + strlen(str) + 1]; strcpy(newstr, str_); strcpy(newstr + length_, str); delete[] str_; length_ += strlen(str); str_ = newstr; return *this; } MyString& MyString::operator=(const MyString& rhs) { /* don't do anything if object assigns itself */ if (this == &rhs) return *this; length_ = rhs.length_; delete[] str_; str_ = new char[ length_ + 1]; strcpy(str_, rhs.str_); /* assignment operator requires this */ return *this; } bool operator==(const MyString& lhs, const MyString& rhs) { if (lhs.length_ != rhs.length_) return false; if (strcmp(lhs.str_, rhs.str_) == 0) return true; else return false; } /* seems like the ostream& in front has nothing to do with dereferencing a pointer, * but it seems like the & is placed there so we can make consecutive overloaded * calls to cout, effectively chaining all of the calls */ ostream& operator<<(ostream& ostr, const MyString& rhs) { return (ostr << rhs.str_); }