Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Can you please add Preconditions and Post conditions for the code below: main.cp

ID: 3697708 • Letter: C

Question

Can you please add Preconditions and Post conditions for the code below:

main.cpp

#include "mystring.h"
#include <fstream>
#include <cctype>      // for toupper()
#include <string>     // for strchr(), strstr(), etc.
#include <cassert>
#include <iostream>
using namespace std;
using namespace cs2b_mystring;

bool eof(istream& in);
void BasicTest();
void RelationTest();
void ConcatTest();
void CopyTest();
myString AppendTest(const myString& ref, myString val);

int main()
{
   BasicTest();
   RelationTest();
   ConcatTest();
   CopyTest();
   return 0;
}

bool eof(istream& in)
{
   char ch;
   in >> ch;
   in.putback(ch);
   return !in;
}


void BasicTest()
{
   myString s;
   cout << "----- Testing basic String creation & printing" << endl;

   const myString strs[] =
   {myString("Wow"), myString("C++ is neat!"),
   myString(""), myString("a-z")};


   for (int i = 0; i < 4; i++){
       cout << "string [" << i <<"] = " << strs[i] << endl;
   }

   cout << endl << "----- Now reading myStrings from file" << endl;

   cout << endl << "----- first, word by word" << endl;
   ifstream in("data.txt");
   if (!in.is_open()){
       std::cerr<<"file open fialed"<<endl;
       return;
   }
   assert(in);
   while (in.peek() == '#'){
       in.ignore(128, ' ');
   }
   in >> s;
   while (in) {
       cout << "Read string = " << s << endl;
       in >> s;
   }
   in.close();


   cout << endl << "----- now, line by line" << endl;
   ifstream in2("data.txt");
   assert(in2);
   while (in2.peek() == '#'){
       in2.ignore(128, ' ');
   }
   s.read(in2, ' ');
   while (in2) {
       cout << "Read string = " << s << endl;
       s.read(in2, ' ');
   }

   cout << endl << "----- Testing access to characters (using const)" << endl;
   const myString s1("abcdefghijklmnopqsrtuvwxyz");
   cout << "Whole string is " << s1 << endl;
   cout << "now char by char: ";
   for (size_t i = 0; i < s1.length(); i++){
       cout << s1[i];
   }

   cout << endl << "----- Testing access to characters (using non-const)" << endl;
   myString s2("abcdefghijklmnopqsrtuvwxyz");
   cout << "Start with " << s2;
   for (size_t i = 0; i < s2.length(); i++){
       s2[i] = toupper(s2[i]);
   }
   cout << " and convert to " << s2 << endl;
}

void RelationTest()
{
   cout << " ----- Testing relational operators between myStrings ";

   const myString strs[] =
   {myString("app"), myString("apple"), myString(""),
   myString("Banana"), myString("Banana")};

   for (int i = 0; i < 4; i++) {
       cout << "Comparing " << strs[i] << " to " << strs[i+1] << endl;
       cout << "    Is left < right? " << (strs[i] < strs[i+1]) << endl;
       cout << "    Is left <= right? " << (strs[i] <= strs[i+1]) << endl;
       cout << "    Is left > right? " << (strs[i] > strs[i+1]) << endl;
       cout << "    Is left >= right? " << (strs[i] >= strs[i+1]) << endl;
       cout << "    Does left == right? " << (strs[i] == strs[i+1]) << endl;
       cout << "    Does left != right ? " << (strs[i] != strs[i+1]) << endl;
   }

   cout << " ----- Testing relations between myStrings and char * ";
   myString s("he");
   const char *t = "hello";
   cout << "Comparing " << s << " to " << t << endl;
   cout << "    Is left < right? " << (s < t) << endl;
   cout << "    Is left <= right? " << (s <= t) << endl;
   cout << "    Is left > right? " << (s > t) << endl;
   cout << "    Is left >= right? " << (s >= t) << endl;
   cout << "    Does left == right? " << (s == t) << endl;
   cout << "    Does left != right ? " << (s != t) << endl;

   myString u("wackity");
   const char *v = "why";
   cout << "Comparing " << v << " to " << u << endl;
   cout << "    Is left < right? " << (v < u) << endl;
   cout << "    Is left <= right? " << (v <= u) << endl;
   cout << "    Is left > right? " << (v > u) << endl;
   cout << "    Is left >= right? " << (v >= u) << endl;
   cout << "    Does left == right? " << (v == u) << endl;
   cout << "    Does left != right ? " << (v != u) << endl;

}

void ConcatTest()
{
   cout << " ----- Testing concatentation on myStrings ";

   const myString s[] =
   {myString("outrageous"), myString("milk"), myString(""),
   myString("cow"), myString("bell")};

   for (int i = 0; i < 4; i++) {
       cout << s[i] << " + " << s[i+1] << " = " << s[i] + s[i+1] << endl;
   }

   cout << " ----- Testing concatentation between myString and char * ";

   const myString a("abcde");
   const char *b = "XYZ";
   cout << a << " + " << b << " = " << a + b << endl;
   cout << b << " + " << a << " = " << b + a << endl;

   cout << " ----- Testing shorthand concat/assign on myStrings ";

   myString s2[] =
   {myString("who"), myString("what"), myString("WHEN"),
   myString("Where"), myString("why")};

   for (int i = 0; i < 4; i++) {
       cout << s2[i] << " += " << s2[i+1] << " = ";
       cout << (s2[i] += s2[i+1]) << endl;
   }

   cout << " ----- Testing shorthand concat/assign using char * ";
   myString u("I love ");
   const char *v = "programming";
   cout << u << " += " << v << " = ";
   cout << (u += v) << endl;
}

myString AppendTest(const myString& ref, myString val)
{
   val[0] = 'B';
   return val + ref;
}

void CopyTest()
{
   cout << " ----- Testing copy constructor and operator= on myStrings ";

   myString orig("cake");


   myString copy(orig);    // invoke copy constructor

   copy[0] = 'f'; // change first letter of the *copy*
   cout << "original is " << orig << ", copy is " << copy << endl;


   myString copy2;      // makes an empty string

   copy2 = orig;        // invoke operator=
   copy2[0] = 'f';      // change first letter of the *copy*
   cout << "original is " << orig << ", copy is " << copy2 << endl;

   copy2 = "Copy Cat";
   copy2 = copy2;        // copy onto self and see what happens
   cout << "after self assignment, copy is " << copy2 << endl;

   cout << "Testing pass & return myStrings by value and ref" << endl;
   myString val = "winky";
   myString sum = AppendTest("Boo", val);
   cout << "after calling Append, sum is " << sum << endl;
   cout << "val is " << val << endl;
   val = sum;
   cout << "after assign, val is " << val << endl;

}

myString.cpp

#include "myString.h"
#include <string.h>
#include <cassert>
namespace cs2b_mystring{

   myString::myString(void)
       :_raw(NULL)
   {
   }

   myString::myString(const char *rawString)
   {
       construction(rawString);
   }

   myString::myString(const myString &other)
   {
       construction(other._raw);
   }

   void myString::construction(const char *src)
   {
       assert(src!=NULL);
       size_t size = strlen(src)+1;
       _raw = new char[size];
       memcpy(_raw,src,size*sizeof(char));
   }

   ostream& operator<<(ostream &out, const myString &str)
   {
       size_t size = str.length();
       for (size_t i=0; i<size; ++i){
           cout<<str[i];
       }
       cout.flush();
       //or use printf(...);
       return out;
   }

   istream& operator>>(istream &in, myString &str)
   {
       char ch = in.peek();
       //skip leading-space
       while (!in.eof() && (ch == ' ' || ch == ' ')){
           in.get();
           ch = in.peek();
       }
       if (str.isValid()){
           delete[]str._raw;
           str._raw = NULL;
       }
       char readStr[127];
       size_t count = 0;
       while (!in.eof() && (ch != ' ' && ch != ' ') && count < 126){
           in.get();
           readStr[count++] = ch;
           ch = in.peek();
       }
       str._raw = new char[count + 1];
       memcpy(str._raw, readStr, sizeof(char)*count);
       str._raw[count]='';
       return in;
   }

   myString::~myString(void)
   {
       if (_raw != NULL){
           delete[]_raw;
       }
   }

   void myString::read(istream &in, int endOfCharh)
   {
       char readStr[127];
       in.getline(readStr, 127, endOfCharh);
       if (_raw != NULL){
           delete[]_raw;
       }
       size_t len = strlen(readStr)+1;
       _raw = new char[len];
       memcpy(_raw,readStr,sizeof(char)*len);

   }

   char& myString::operator[](const size_t pos)
   {
       assert(length()>pos);
       return _raw[pos];
   }

   const char& myString::operator[](const size_t pos) const
   {
       assert(length()>pos);
       return _raw[pos];
   }

   bool myString::operator<(const myString &rhs)const
   {
       return (*this < rhs._raw);
   }

   bool myString::operator<(const char *rhs)const
   {
       if (!isValid() || !rhs){
           return false;
       }
       return strcmp(_raw, rhs)<0;
   }

   bool myString::operator<=(const myString &rhs)const
   {
       return (*this <= rhs._raw);
   }

   bool myString::operator<=(const char *rhs)const
   {
       if (!isValid() || !rhs){
           return false;
       }
       return strcmp(_raw, rhs)<=0;
   }

   bool myString::operator>(const myString &rhs)const
   {
       return !(*this <= rhs);
   }

   bool myString::operator>(const char *rhs)const
   {
       return !(*this <= rhs);
   }

   bool myString::operator>=(const myString &rhs)const
   {
       return !(*this < rhs);
   }

   bool myString::operator>=(const char *rhs)const
   {
       return !(*this < rhs);
   }

   bool myString::operator==(const myString &rhs)const
   {
       return (*this == rhs._raw);
   }

   bool myString::operator==(const char *rhs)const
   {
       if (!isValid() || !rhs){
           return false;
       }
       return strcmp(_raw, rhs)==0;
   }

   bool myString::operator!=(const myString &rhs)const
   {
       return !(*this==rhs);
   }

   bool myString::operator!=(const char *rhs)const
   {
       return !(*this==rhs);
   }

   myString myString::operator+(const myString &rhs)const
   {
       return *this+rhs._raw;
   }

   myString myString::operator+(const char *rhs)const
   {
       size_t first = length();
       size_t second = rhs ? strlen(rhs) : 0;
       size_t totall = first+second+1;
       myString newStr;
       newStr._raw = new char[totall];
       char *p = newStr._raw;
       memcpy(p,_raw,first*sizeof(char));
       memcpy(p+first,rhs,(second)*sizeof(char));
       *(p+totall-1) = '';
       return newStr;
   }
   myString operator+(const char* lhs,const myString &rhs)
   {
       myString str(lhs);
       return str+rhs;
   }

   myString& myString::operator+=(const myString &rhs)
   {
       return *this+=rhs._raw;
   }

   myString& myString::operator+=(const char *rhs)
   {
       size_t first = length();
       size_t second = rhs ? strlen(rhs) : 0;
       size_t totall = first+second+1;
       char *newStr = new char[totall];
       memcpy(newStr, _raw, first*sizeof(char));
       memcpy(newStr+first,rhs, second*sizeof(char));
       *(newStr+totall-1) = '';
       if (_raw != NULL){
           delete[]_raw;
       }
       _raw = newStr;
       return *this;
   }

   size_t myString::length()const
   {
       return _raw ? strlen(_raw) : 0;
   }

   bool myString::isValid() const
   {
       return _raw!=NULL;
   }

   myString& myString::operator=(const myString &rhs)
   {
       if (this->equal(rhs)){
           return *this;
       }
       if (_raw != NULL){
           delete[]_raw;
       }
       int len = rhs.length();
       _raw = new char[len+1];
       memcpy(_raw, rhs._raw, sizeof(char)*len);
       _raw[len] = '';
       return *this;
   }

   bool myString::equal(const myString &other)
   {
       return _raw == other._raw;
   }

}


myString.h


#pragma once
#include <iostream>
using std::cout;
using std::cin;
using std::ostream;
using std::istream;
namespace cs2b_mystring{

   class myString
   {
   public:
       //construct empty
       myString(void);
       //constructed by c-string
       myString(const char *rawString);
       //deep-copy;
       myString(const myString &other);
       //operator=
       myString& operator=(const myString &rhs);
       //operator<<
       friend ostream& operator<<(ostream &out, const myString &str);
       //operator>>, skip leading spaces, and end by space,limit length = 127(contains end of sequence)
       friend istream& operator>>(istream &in, myString &str);
       //ready read readyToReadLength sizes from istream-in, and then return size of reading factly
       //limit length = 127(contains end of sequence)
       void read(istream &in, int endOfChar);
       //operator[]
       char& operator[](const size_t pos);
       //operator[]const
       const char& operator[](const size_t pos)const;
       //relational operators
       bool operator<(const myString &rhs)const;
       bool operator<(const char *rhs)const;
       bool operator<=(const myString &rhs)const;
       bool operator<=(const char *rhs)const;
       bool operator>(const myString &rhs)const;
       bool operator>(const char *rhs)const;
       bool operator>=(const myString &rhs)const;
       bool operator>=(const char *rhs)const;
       bool operator==(const myString &rhs)const;
       bool operator==(const char *rhs)const;
       bool operator!=(const myString &rhs)const;
       bool operator!=(const char *rhs)const;
       //friend functins of relational operators
       friend bool operator<(const char* lhs, const myString &rhs){return !(rhs < lhs);}
       friend bool operator<=(const char* lhs, const myString &rhs){return !(rhs <= lhs);}
       friend bool operator>(const char* lhs, const myString &rhs){return !(rhs > lhs);}
       friend bool operator>=(const char* lhs, const myString &rhs){return !(rhs >= lhs);}
       friend bool operator==(const char* lhs, const myString &rhs){return (rhs == lhs);}
       friend bool operator!=(const char* lhs, const myString &rhs){return rhs != lhs;}
       //combine
       myString operator+(const myString &rhs)const;
       myString operator+(const char *rhs)const;
       friend myString operator+(const char* lhs,const myString &rhs);
      
       myString& operator+=(const myString &rhs);
       myString& operator+=(const char *rhs);
       ~myString(void);
       size_t length()const;
   protected:
       void construction(const char *src);
       //by address of _raw
       bool equal(const myString &other);
       //return true if _raw is not equal NULL
       bool isValid()const;
   private:
       char *_raw;
   };

}

Explanation / Answer

main.cpp

#include "mystring.h"
#include <fstream>
#include <cctype>      // for toupper()
#include <string>
#include <cassert>
#include <iostream>
using namespace std;
using namespace cs2b_mystring;

bool eof(istream& in);
void BasicTest();
void RelationTest();
void ConcatTest();
void CopyTest();
myString AppendTest(const myString& ref, myString val);
string boolString(bool convertMe);


int main()
{
   BasicTest();
   RelationTest();
   ConcatTest();
   CopyTest();
}

bool eof(istream& in)
{
   char ch;
   in >> ch;
   in.putback(ch);
   return !in;
}

string boolString(bool convertMe) {
   if (convertMe) {
      return "true";
   } else {
      return "false";
   }
}


void BasicTest()
{
   myString s;
   cout << "----- Testing basic String creation & printing" << endl;

   const myString strs[] =
   {myString("Wow"), myString("C++ is neat!"),
      myString(""), myString("a-z")};


   for (int i = 0; i < 4; i++){
      cout << "string [" << i <<"] = " << strs[i] << endl;
   }

   cout << endl << "----- Now reading myStrings from file" << endl;

   cout << endl << "----- first, word by word" << endl;
   ifstream in("mystring.txt");
   assert(in);
   while (in.peek() == '#'){
      in.ignore(128, ' ');
   }
   in >> s;
   while (in) {
      cout << "Read string = " << s << endl;
      in >> s;
   }
   in.close();
   cout << endl << "----- now, line by line" << endl;
   ifstream in2("mystring.txt");
   assert(in2);
   while (in2.peek() == '#'){
      in2.ignore(128, ' ');
   }
   s.read(in2, ' ');
   while (in2) {
      cout << "Read string = " << s << endl;
      s.read(in2, ' ');
   }
   cout << endl << "----- Testing access to characters (using const)" << endl;
   const myString s1("abcdefghijklmnopqsrtuvwxyz");
   cout << "Whole string is " << s1 << endl;
   cout << "now char by char: ";
   for (int i = 0; i < s1.length(); i++){
      cout << s1[i];
   }

   cout << endl << "----- Testing access to characters (using non-const)" << endl;
   myString s2("abcdefghijklmnopqsrtuvwxyz");
   cout << "Start with " << s2;
   for (int i = 0; i < s2.length(); i++){
      s2[i] = toupper(s2[i]);
   }
   cout << " and convert to " << s2 << endl;
}

void RelationTest()
{
   cout << " ----- Testing relational operators between myStrings ";

   const myString strs[] =
   {myString("app"), myString("apple"), myString(""),
      myString("Banana"), myString("Banana")};

   for (int i = 0; i < 4; i++) {
      cout << "Comparing " << strs[i] << " to " << strs[i+1] << endl;
      cout << " Is left < right? " << boolString(strs[i] < strs[i+1]) << endl;
      cout << " Is left <= right? " << boolString(strs[i] <= strs[i+1]) << endl;
      cout << " Is left > right? " << boolString(strs[i] > strs[i+1]) << endl;
      cout << " Is left >= right? " << boolString(strs[i] >= strs[i+1]) << endl;
      cout << " Does left == right? " << boolString(strs[i] == strs[i+1]) << endl;
      cout << " Does left != right ? " << boolString(strs[i] != strs[i+1]) << endl;
   }

   cout << " ----- Testing relations between myStrings and char * ";
   myString s("he");
   const char *t = "hello";
   cout << "Comparing " << s << " to " << t << endl;
   cout << " Is left < right? " << boolString(s < t) << endl;
   cout << " Is left <= right? " << boolString(s <= t) << endl;
   cout << " Is left > right? " << boolString(s > t) << endl;
   cout << " Is left >= right? " << boolString(s >= t) << endl;
   cout << " Does left == right? " << boolString(s == t) << endl;
   cout << " Does left != right ? " << boolString(s != t) << endl;

   myString u("wackity");
   const char *v = "why";
   cout << "Comparing " << v << " to " << u << endl;
   cout << " Is left < right? " << boolString(v < u) << endl;
   cout << " Is left <= right? " << boolString(v <= u) << endl;
   cout << " Is left > right? " << boolString(v > u) << endl;
   cout << " Is left >= right? " << boolString(v >= u) << endl;
   cout << " Does left == right? " << boolString(v == u) << endl;
   cout << " Does left != right ? " << boolString(v != u) << endl;

}

void ConcatTest()
{
   cout << " ----- Testing concatentation on myStrings ";

   const myString s[] =
   {myString("outrageous"), myString("milk"), myString(""),
      myString("cow"), myString("bell")};

   for (int i = 0; i < 4; i++) {
      cout << s[i] << " + " << s[i+1] << " = " << s[i] + s[i+1] << endl;
   }

   cout << " ----- Testing concatentation between myString and char * ";

   const myString a("abcde");
   const char *b = "XYZ";
   cout << a << " + " << b << " = " << a + b << endl;
   cout << b << " + " << a << " = " << b + a << endl;

   cout << " ----- Testing shorthand concat/assign on myStrings ";

   myString s2[] =
   {myString("who"), myString("what"), myString("WHEN"),
      myString("Where"), myString("why")};

   for (int i = 0; i < 4; i++) {
      cout << s2[i] << " += " << s2[i+1] << " = ";
      cout << (s2[i] += s2[i+1]) << "and";
      cout << s2[i] << endl;
   }

   cout << " ----- Testing shorthand concat/assign using char * ";
   myString u("I love ");
   const char *v = "programming";
   cout << u << " += " << v << " = ";
   cout << (u += v) << endl;
}

myString AppendTest(const myString& ref, myString val)
{
   val[0] = 'B';
   return val + ref;
}

void CopyTest()
{
   cout << " ----- Testing copy constructor and operator= on myStrings ";

   myString orig("cake");


   myString copy(orig);    // invoke copy constructor

   copy[0] = 'f'; // change first letter of the *copy*
   cout << "original is " << orig << ", copy is " << copy << endl;


   myString copy2;      // makes an empty string

   copy2 = orig;        // invoke operator=
   copy2[0] = 'f';      // change first letter of the *copy*
   cout << "original is " << orig << ", copy is " << copy2 << endl;

   copy2 = "Copy Cat";
   copy2 = copy2;        // copy onto self and see what happens
   cout << "after self assignment, copy is " << copy2 << endl;


   cout << "Testing pass & return myStrings by value and ref" << endl;
   myString val = "winky";
   myString sum = AppendTest("Boo", val);
   cout << "after calling Append, sum is " << sum << endl;
   cout << "val is " << val << endl;
   val = sum;
   cout << "after assign, val is " << val << endl;

}

mystring.cpp
#include <iostream>
#include <cassert>
#include "mystring.h"

using namespace std;

namespace cs2b_mystring {

    myString::myString() {
        myCString = new char[1];
        strcpy(myCString, "");
    }
    myString::myString(const char *inMyCString) {
        myCString = new char[strlen(inMyCString)+1];
        strcpy(myCString, inMyCString);
    }
    myString::myString(const myString& right) {
        myCString = new char[strlen(right.myCString)+1];
        strcpy(myCString, right.myCString);
    }
    myString::~myString() {
        delete [] myCString;
    }

    myString myString::operator= (const myString& right) {
        if (this != &right) {
            delete [] myCString;
            myCString = new char[strlen(right.myCString)+1];
            strcpy(myCString, right.myCString);
        }
        return *this;
    }
    ostream& operator<< (ostream& out, const myString& right) {
        out << right.myCString;
        return out;

    }

    istream& operator>> (istream& in, myString& right) {
      
        char inBufferHolder[128];
        in.width(128);
        in >> inBufferHolder;
        delete [] right.myCString;
        right.myCString = new char [strlen(inBufferHolder)+1];
        strcpy(right.myCString, inBufferHolder);
        return in;
    }
    void myString::read(istream& in, char delim) {
        char inBufferHolder[128];
        in.getline(inBufferHolder, 128, delim);
        delete [] myCString;
        myCString = new char [strlen(inBufferHolder)];
        strcpy(myCString, inBufferHolder);
    }
    long myString::length() const {
        return (strlen(myCString));
    }
    bool operator< (const myString& left, const myString& right) {
        return (strcmp(left.myCString,right.myCString) < 0);
    }
    bool operator<= (const myString& left, const myString& right) {
        return (strcmp(left.myCString,right.myCString) <= 0);
    }
    bool operator> (const myString& left, const myString& right) {
        return (strcmp(left.myCString,right.myCString) > 0);
    }
    bool operator>= (const myString& left, const myString& right) {
        return (strcmp(left.myCString,right.myCString) >= 0);
    }
    bool operator== (const myString& left, const myString& right) {
        return (strcmp(left.myCString,right.myCString) == 0);
    }
    bool operator!= (const myString& left, const myString& right) {
        return (strcmp(left.myCString,right.myCString) != 0);
    }
    char myString::operator[](int index) const {
        assert(index >= 0 && index < strlen(myCString));
        return myCString[index];
    }
    char& myString::operator[](int index) {
        assert(index >= 0 && index < strlen(myCString));
        return myCString[index];
    }
    myString operator+ (const myString& left, const myString& right) {
        char *Cstring = new char [strlen(left.myCString) + strlen(right.myCString) + 1];
        myString result = myString(Cstring);
        strcpy(result.myCString, left.myCString);
        strcat(result.myCString, right.myCString);
        return result;
    }
    myString myString::operator+= (const myString& right) {
        *this = *this+right;
        return *this;
    }
  
  
} // namespace end

mystring.h
/*
Public Funtions:

myString();
Precondition:    None.
Postcondition:   An object of class myString has been created, which has a
                  c-string with only ''.

myString(const char *inMyCString);
Precondition:    inMyCString is a c-string.
Postcondition:   An object of class myString has been created, which has a
                  inMyCString c-string.

myString(const myString& right);
Precondition:    right is a myString object.
Postcondition:   An object of class myString has been created, which is a copy
                  of (the myString object) right.

~myString();
Precondition:    The memory for a myString object is being deallocated.
Postcondition:   The variable that myCString was pointing to has had its memory
                  deallocated.

myString operator= (const myString& right);
Precondition:    right is a myString object.
Postcondition:   The variable that the left.myCString was pointing to has been
                  deallocated, and left.myCString now points to a copy of
                  right.myCString.

friend std::ostream& operator<< (std::ostream& out, const myString& right);
Precondition:    out is an ostream. right is a myString object.
Postcondition:   right.myCString is sent to the ostream (out).

friend std::istream& operator>> (std::istream& in, myString& right);
Precondition:    in is an istream. right is a myString variable.
Postcondition:   The istream, in, will read up to 127 characters, ignoring any
                  leading whitespace, and stops at the first whitespace. The
                  variable that right.myCString was pointing to on the heap has
                  had its memory deallocated, and right.myCString is now pointing
                  to a new c-string from the in buffer.

void read(std::istream& in, char delim);
Precondition:    in is an istream. delim is the character that will be the
                  delimiting char for extraction.
Postcondition:   The istream, in, will read up to 127 characters, including any
                  leading whitespace, and stop as the first occurence of the
                  char, delim. The variable that right.myCString was pointing to
                  on the heap has had its memory deallocated, and right.myCString
                  is now pointing to a new c-string from the in buffer.

long length() const;
Precondition:    None.
Postcondition:   Returns a long with the value of strlen(myCString).

friend bool operator< (const myString& left, const myString& right);
Precondition:    left and right are myString objects or c-strings.
Postcondition:   Returns a boolean representing the relationship between left
                  and right. Returns true if strcmp(left.myCString,right.myCString)
                  is less than 0, false otherwise.

friend bool operator<= (const myString& left, const myString& right);
Precondition:    left and right are myString objects or c-strings.
Postcondition:   Returns a boolean representing the relationship between left
                  and right. Returns true if strcmp(left.myCString,right.myCString)
                  is less than or equal to 0, false otherwise.

friend bool operator> (const myString& left, const myString& right);
Precondition:    left and right are myString objects or c-strings.
Postcondition:   Returns a boolean representing the relationship between left
                  and right. Returns true if strcmp(left.myCString,right.myCString)
                  is greater than 0, false otherwise.

friend bool operator>= (const myString& left, const myString& right);
Precondition:    left and right are myString objects or c-strings.
Postcondition:   Returns a boolean representing the relationship between left
                  and right. Returns true if strcmp(left.myCString,right.myCString)
                  is greater than or equal to 0, false otherwise.

friend bool operator== (const myString& left, const myString& right);
Precondition:    left and right are myString objects or c-strings.
Postcondition:   Returns a boolean representing the relationship between left
                  and right. Returns true if strcmp(left.myCString,right.myCString)
                  is 0, false otherwise.

friend bool operator!= (const myString& left, const myString& right);
Precondition:    left and right are myString objects or c-strings.
Postcondition:   Returns a boolean representing the relationship between left
                  and right. Returns true if strcmp(left.myCString,right.myCString)
                  is not 0, false otherwise.

char operator[](int index) const;
Precondition:    Calling object is a const myString object.
Postcondition:   Returns the value of myCString[index].

char& operator[](int index);
Precondition:    Calling object is a myString object (not const).
Postcondition:   Returns a reference to myCString[index].

friend myString operator+ (const myString& left, const myString& right);
Precondition:    left and right are myString objects or c-strings.
Postcondition:   Returns a new myString object, whose myCString data member
                  points to a new c-string on the heap with a value of the
                  concatenation of left.myCString and right.myCString.

myString operator+= (const myString& right);
Precondition:    right is a myString object or a c-string.
Postcondition:   myCString is assigned the value of the concatenation of
                  right.myCString and myCString.
*/


#ifndef MYSTRING_H
#define MYSTRING_H

#include <iostream>

namespace cs2b_mystring {

   class myString {
   public:
      myString();
      myString(const char *inMyCString);
      myString(const myString& right);
      ~myString();
      myString operator= (const myString& right);
      friend std::ostream& operator<< (std::ostream& out, const myString& right);
      friend std::istream& operator>> (std::istream& in, myString& right);
      void read(std::istream& in, char delim);
      long length() const;
      friend bool operator< (const myString& left, const myString& right);
      friend bool operator<= (const myString& left, const myString& right);
      friend bool operator> (const myString& left, const myString& right);
      friend bool operator>= (const myString& left, const myString& right);
      friend bool operator== (const myString& left, const myString& right);
      friend bool operator!= (const myString& left, const myString& right);
      char operator[](int index) const;
      char& operator[](int index);
      friend myString operator+ (const myString& left, const myString& right);
      myString operator+= (const myString& right);
   private:
      char *myCString;
   }; // class end
} // namespace end

#endif


Sample Output:
----- Testing basic String creation & printing
string [0] = Wow
string [1] = C++ is neat!
string [2] =
string [3] = a-z

----- Now reading myStrings from file

----- first, word by word
Read string = The
Read string = first
Read string = time
Read string = we
Read string = will
Read string = read
Read string = individual
Read string = words,
Read string = next
Read string = we
Read string = read
Read string = whole
Read string = lines

----- now, line by line
Read string = The first time we will
Read string =     read individual words, next
Read string = we read whole lines

----- Testing access to characters (using const)
Whole string is abcdefghijklmnopqsrtuvwxyz
now char by char: abcdefghijklmnopqsrtuvwxyz
----- Testing access to characters (using non-const)
Start with abcdefghijklmnopqsrtuvwxyz and convert to ABCDEFGHIJKLMNOPQSRTUVWXYZ

----- Testing relational operators between myStrings
Comparing app to apple
   Is left < right? true
   Is left <= right? true
   Is left > right? false
   Is left >= right? false
   Does left == right? false
   Does left != right ? true
Comparing apple to
   Is left < right? false
   Is left <= right? false
   Is left > right? true
   Is left >= right? true
   Does left == right? false
   Does left != right ? true
Comparing to Banana
   Is left < right? true
   Is left <= right? true
   Is left > right? false
   Is left >= right? false
   Does left == right? false
   Does left != right ? true
Comparing Banana to Banana
   Is left < right? false
   Is left <= right? true
   Is left > right? false
   Is left >= right? true
   Does left == right? true
   Does left != right ? false

----- Testing relations between myStrings and char *
Comparing he to hello
   Is left < right? true
   Is left <= right? true
   Is left > right? false
   Is left >= right? false
   Does left == right? false
   Does left != right ? true
Comparing why to wackity
   Is left < right? false
   Is left <= right? false
   Is left > right? true
   Is left >= right? true
   Does left == right? false
   Does left != right ? true

----- Testing concatentation on myStrings
outrageous + milk = outrageousmilk
milk + = milk
+ cow = cow
cow + bell = cowbell

----- Testing concatentation between myString and char *
abcde + XYZ = abcdeXYZ
XYZ + abcde = XYZabcde

----- Testing shorthand concat/assign on myStrings
who += what = whowhatandwhowhat
what += WHEN = whatWHENandwhatWHEN
WHEN += Where = WHENWhereandWHENWhere
Where += why = WherewhyandWherewhy

----- Testing shorthand concat/assign using char *
I love += programming = I love programming

----- Testing copy constructor and operator= on myStrings
original is cake, copy is fake
original is cake, copy is fake
after self assignment, copy is Copy Cat
Testing pass & return myStrings by value and ref
after calling Append, sum is BinkyBoo
val is winky
after assign, val is BinkyBoo