Listing 2 String Class Implementation

// string.cpp

#include <iostream.h>
#include <iomanip.h>
#include <string.h>
#include <assert.h>
#include "string.hpp"

string::string(const char *s, size_t n)
{
    assert(s);
    clone(s,n);
}

string& string::operator=(const string& s)
{
    if (this != &s)
    {
        delete [] data;
        clone(s.data,s.count);
    }
    return *this;
}

string& string::operator+=(const string& s)
{
    assert(count + s.count < NPOS);
    if (s.count > 0)
    {
        int new_count = count + s.count;
        char *buf = new char[new_count + 1];

        memcpy(buf,data,count);
        memcpy(buf+count,s.data,s.count);
        buf[new_count] = '\0';
        delete [] data;
        data = buf;
        count = new_count;
    }
    return *this;
}

size_t string::find(const string& s, size_t pos) const
{
    assert(pos < count);
    char *p = strstr(data,s.c_str());
    if (p)
        return pos + (p - data);
    return NPOS;
}

size_t string::find_first_of(const string& s, size_t pos) const
{
    assert(pos < count);
    char *p = strpbrk(data+pos,s.data);
    if (p)
        return p - data;
    return NPOS;
}

size_t string::find_first_not_of(const string& s, size_t pos) const
{
    assert(pos < count);
    for (size_t i = pos; i < count; ++i)
        if (strchr(s.data,data[i]) == NULL)
            return i;
    return NPOS;
}

string string::substr(size_t pos, size_t n) const
{
    assert(pos <= count);
    if (n > count - pos)
        n = count - pos;

    if (n > 0)
        return string(data+pos,n);
    else
        return string();   // Empty string
}
ostream& operator<<(ostream& os, const string& s)
{
    os.write(s.data,s.count);
    return os;
}

istream& operator>>(istream& is, string& s)
{
    const size_t BUFSIZ = 256;
    char buf[BUFSIZ];

    is >> setw(BUFSIZ) >> buf;
    s.clone(buf,strlen(buf));
    return is;
}

void string::put_at(size_t pos, char c)
{
    assert(pos <= count);
    if (pos < count)
        data[pos] = c;
    else
    {
        // Append character the lazy way
        char buf[2];
        baf[0] = c;
        buf[1] = '\0';
        operator+=(buf);
    }
}

int operator==(const string& s1, const string& s2)
{
    return s1.count == s2.count &&
     memcmp(s1.data,s2.data,s1.count) == 0;
}

int operator!=(const string& s1, const string& s2)
{
    return s1.count != s2.count ||
     memcmp(s1.data,s2.data,s1.count);
}

// Private function
void string::clone(const char *s, size_t n)
{
    // Assumes "data" needs to be allocated
    assert(s != NULL);
    size_t len = strlen(s);
    count = (n >= len) ? len : n;
    data = new char[count + 1];
    strncpy(data,s,count)[count] = '\0';
}

// End of File