summaryrefslogtreecommitdiffstats
path: root/string.cpp
blob: 393368f323ef9f8aa7701abec00e958cb0c6be23 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
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_);
}