From 43898d9c59fe06622f651cb8f1d885cbcadca85d Mon Sep 17 00:00:00 2001 From: Kamil Kaminski Date: Wed, 6 Jul 2011 20:33:45 -0500 Subject: initial import --- Makefile | 44 +++++++++++++++++++ main.cpp | 29 ++++++++++++ string.cpp | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ string.h | 73 +++++++++++++++++++++++++++++++ 4 files changed, 292 insertions(+) create mode 100644 Makefile create mode 100644 main.cpp create mode 100644 string.cpp create mode 100644 string.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e3f62e8 --- /dev/null +++ b/Makefile @@ -0,0 +1,44 @@ +BIN = string +SRC = main.cpp string.cpp +CC = g++ +CFLAGS = -Wall -std=gnu++98 -pedantic -MD +DBGFLAGS = -g -O0 +ifdef DEBUG + CFLAGS += $(DBGFLAGS) +else + CFLAGS += -O2 -march=native -mtune=native +endif +LDFLAGS = -lm + +OBJ_DIR = obj +DEPS_DIR = obj +BIN_DIR = bin + +CPP_FILES = $(filter %.cpp, $(SRC)) +DEP_FILES = $(addprefix $(DEPS_DIR)/, $(addsuffix .d, $(notdir $(subst .cpp,,$(SRC))))) +OBJ_FILES = $(addprefix $(OBJ_DIR)/, $(addsuffix .o, $(notdir $(subst .cpp,,$(SRC))))) + +INCL = -I/include + +define CPP_template +$(1): $(2) + @mkdir -p $$(OBJ_DIR) + @mkdir -p $$(DEPS_DIR) + $$(CC) -c $$(CFLAGS) $$(INCL) $$< -o $$@ +endef + +all: $(BIN) + +$(foreach cppfile, $(CPP_FILES), $(eval $(call CPP_template, $(OBJ_DIR)/$(notdir $(subst .cpp,,$(cppfile))).o, $(cppfile)))) + +$(BIN): $(OBJ_FILES) + @mkdir -p $(BIN_DIR) + $(CC) $(LDFLAGS) $(OBJ_FILES) -o $(BIN_DIR)/$@ + +.PHONY: clean + +clean: + rm -rf $(OBJ_DIR) + rm -f $(BIN_DIR)/$(BIN) + +-include $(DEP_FILES) diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..b951358 --- /dev/null +++ b/main.cpp @@ -0,0 +1,29 @@ +#include "string.h" + +int main(int argc, char **argv) +{ + MyString mystr("alpha"); + if (mystr.isSubstring("ph")) + { + cout << "true" << endl; + } + else + cout << "false" << endl; + + MyString mystr1 = ", beta"; + MyString mystr2 = ", charlie"; + MyString mystr3 = ", delta"; + + mystr.concat(mystr1).concat(mystr2).concat(mystr3); + cout << mystr << endl; + + MyString mystr4 = "hello"; + mystr4.concat(", world!").concat(" goodbye"); + cout << mystr4 << endl; + + MyString mystr5 = "bro"; + cout << mystr5 << endl; + + return 0; +} + 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 + +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_); +} + diff --git a/string.h b/string.h new file mode 100644 index 0000000..dc9ebfc --- /dev/null +++ b/string.h @@ -0,0 +1,73 @@ +/* string.h + * + */ + +#ifndef _MYSTRING_ +#define _MYSTRING_ + +#include +#include + +using namespace std; + +class MyString +{ + friend bool operator==(const MyString&, const MyString &); + friend ostream& operator<<(ostream&, const MyString &); + + private: + char *str_; + int length_; + MyString(int); + + public: + MyString(); + MyString(char); + MyString(const char *); + MyString(const MyString &); + MyString& operator=(const MyString &); + ~MyString(); + + int length() const; + int indexOf(char, int = 0) const; + bool isSubstring(const MyString &) const; + bool isSubstring(const char *) const; + MyString& concat(const MyString &); + MyString& concat(const char *); + void printStr(void) const; + + MyString operator!() const; + char& operator[](int); + char operator[](int) const; +}; + +bool operator==(const MyString&, const MyString &); +ostream& operator<<(ostream&, const MyString &); + +inline MyString::MyString() +{ + length_ = 0; + str_ = new char[1]; + str_[0] = '\0'; +} + +inline MyString::MyString(char ch) +{ + length_ = 1; + str_ = new char[2]; + str_[0] = ch; + str_[1] = '\0'; +} + +inline int MyString::length() const +{ + return length_; +} + +inline void MyString::printStr(void) const +{ + cout << "length: " << length_ << ", value: \"" << str_ <<"\""; +} + +#endif + -- cgit v1.2.3