summaryrefslogtreecommitdiffstats
path: root/string.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'string.cpp')
-rw-r--r--string.cpp146
1 files changed, 146 insertions, 0 deletions
diff --git a/string.cpp b/string.cpp
new file mode 100644
index 0000000..393368f
--- /dev/null
+++ b/string.cpp
@@ -0,0 +1,146 @@
+/* string.cpp
+ *
+ * Note: http://msdn.microsoft.com/en-us/magazine/cc163742.aspx
+ *
+ */
+
+#include "string.h"
+#include <sstream>
+
+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_);
+}
+