L
Luis
Below is my project. My Code is done, but when I try to compile it, my IDE
crahses (again). I fixed up all the things you guys said I should, except
for some which would not meet the project requiremnts. here is my code. it
compiles, but crashes winsioux.
#ifndef MYSTRING_H
#define MYSTRING_H
#include <iostream>
using namespace std;
class MyString {
public:
//Constructors, Copy, and Destrctors
MyString(); //one of four
MyString(const char *inString); //two of four
MyString operator=(const MyString right); //three of four
MyString(const MyString &right); //four of four
~MyString(); //destructor
//input/output
int length()const;
friend ostream& operator<<(ostream& out,const MyString &outString);
friend istream& operator>>(istream& in,MyString &inString);
void read(istream& inString,char delimit);
//Overloaded brackets
char& operator[](int index);
char operator[](int index)const;
friend MyString operator+(const MyString left,const MyString right);
MyString& operator+=( 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);
friend bool operator!=(const MyString &left, const MyString &right);
private:
char * string;
};
#endif
/*
* -------------------
* These functions are designed to help you test your MyString objects,
* as well as show the client usage of the class.
*
* The BasicTest function builds an array of strings using various
* constructor options and prints them out. It also uses the String
* stream operations to read some strings from a data file.
*
* The RelationTest function checks out the basic relational operations
* (==, !=, <, etc) on Strings and char *s.
*
* The ConcatTest functions checks the overloaded + and += operators that
* do string concatenation.
*
* The CopyTest tries out the copy constructor and assignment operators
* to make sure they do a true deep copy.
*
* Although not exhaustive, these tests will help you to exercise the basic
* functionality of the class and show you how a client might use it.
*
* While you are developing your MyString class, you might find it
* easier to comment out functions you are ready for, so that you don't
* get lots of compile/link complaints.
*/
#include "mystring.h"
#include <fstream>
#include <cctype> // for toupper()
#include <string> // for strchr(), strstr(), etc.
#include <cassert>
#include <iostream>
using namespace std;
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();
}
bool eof(istream& in)
{
char ch;
in >> ch;
in.putback(ch);
return !in;
}
void BasicTest()
{
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 << endl;
}
cout << endl << "----- Now reading MyStrings from file" << endl;
cout << endl << "----- first, word by word" << endl;
ifstream in("string.data");
assert(in);
while (!eof(in)) {
MyString s; // creates an empty string
if (in.peek() == '#') { // peek at char, comments start with #
in.ignore(128, '\n'); // skip this line, it's a comment
} else {
in >> s;
cout << "Read string = " << s << endl;
}
}
in.close();
cout << endl << "----- now, line by line" << endl;
ifstream in2("string.data");
assert(in2);
while (!eof(in2)) {
MyString s; // creates an empty string
if (in2.peek() == '#') { // peek at char, comments start with #
in2.ignore(128, '\n'); // skip this line, it's a comment
} else {
s.read(in2, '\n');
cout << "Read string = " << s << endl;
}
}
in2.close();
cout << endl << "----- Testing access to characters (using const)" <<
endl;
const MyString s("abcdefghijklmnopqsrtuvwxyz");
cout << "Whole string is " << s << endl;
cout << "now char by char: ";
for (int i = 0; i < s.length(); i++){
cout << s;
}
cout << endl << "----- Testing access to characters (using non-const)"
<< endl;
MyString s2("abcdefghijklmnopqsrtuvwxyz");
cout << "Start with " << s2;
for (int i = 0; i < s.length(); i++){
s2 = toupper(s2);
}
cout << " and convert to " << s2 << endl;
}
void RelationTest()
{
cout << "\n----- Testing relational operators between MyStrings\n";
const MyString strs[] =
{MyString("app"), MyString("apple"), MyString(""),
MyString("Banana"), MyString("Banana")};
for (int i = 0; i < 4; i++) {
cout << "Comparing " << strs << " to " << strs[i+1] << endl;
cout << "\tIs left < right? " << (strs < strs[i+1]) << endl;
cout << "\tIs left <= right? " << (strs <= strs[i+1]) << endl;
cout << "\tIs left > right? " << (strs > strs[i+1]) << endl;
cout << "\tIs left >= right? " << (strs >= strs[i+1]) << endl;
cout << "\tDoes left == right? " << (strs == strs[i+1]) << endl;
cout << "\tDoes left != right ? " << (strs != strs[i+1]) << endl;
}
cout << "\n----- Testing relations between MyStrings and char *\n";
MyString s("he");
const char *t = "hello";
cout << "Comparing " << s << " to " << t << endl;
cout << "\tIs left < right? " << (s < t) << endl;
cout << "\tIs left <= right? " << (s <= t) << endl;
cout << "\tIs left > right? " << (s > t) << endl;
cout << "\tIs left >= right? " << (s >= t) << endl;
cout << "\tDoes left == right? " << (s == t) << endl;
cout << "\tDoes left != right ? " << (s != t) << endl;
MyString u("wackity");
const char *v = "why";
cout << "Comparing " << v << " to " << u << endl;
cout << "\tIs left < right? " << (v < u) << endl;
cout << "\tIs left <= right? " << (v <= u) << endl;
cout << "\tIs left > right? " << (v > u) << endl;
cout << "\tIs left >= right? " << (v >= u) << endl;
cout << "\tDoes left == right? " << (v == u) << endl;
cout << "\tDoes left != right ? " << (v != u) << endl;
}
void ConcatTest()
{
cout << "\n----- Testing concatentation on MyStrings\n";
const MyString s[] =
{MyString("outrageous"), MyString("milk"), MyString(""),
MyString("cow"), MyString("bell")};
for (int i = 0; i < 4; i++) {
cout << s << " + " << s[i+1] << " = " << s + s[i+1] << endl;
}
cout << "\n----- Testing concatentation between MyString and char *\n";
const MyString a("abcde");
const char *b = "XYZ";
cout << a << " + " << b << " = " << a + b << endl;
cout << b << " + " << a << " = " << b + a << endl;
cout << "\n----- Testing shorthand concat/assign on MyStrings\n";
MyString s2[] =
{MyString("who"), MyString("what"), MyString("WHEN"),
MyString("Where"), MyString("why")};
for (int i = 0; i < 4; i++) {
cout << s2 << " += " << s2[i+1] << " = ";
cout << (s2 += s2[i+1]) << endl;
}
cout << "\n----- Testing shorthand concat/assign using char *\n";
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 << "\n----- Testing copy constructor and operator= on MyStrings\n";
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::MyString()
{
string = new char[0];
string[0] = 0;
}
MyString::MyString(const char *inString)
{
string = new char[strlen(inString)+1];
strcpy(string,inString);
}
MyString::~MyString()
{
delete []string;
}
ostream& operator<<(ostream &out,const MyString &outString)
{
out<<outString.string;
return out;
}
MyString MyString:: operator=(const MyString right)
{
if (this != &right)
{
delete []string;
string = new char[strlen(right.string)+1];
strcpy(string,right.string);
}
return *this;
}
MyString::MyString(const MyString &right)
{
string = new char[strlen(right.string)+1];
strcpy(string,right.string);
}
char& MyString:
perator[](int index)
{
assert(index>=0 && index < strlen(string));
return string[index];
}
char MyString:
perator[](int index)const
{
assert(index>=0 && index < strlen(string));
return string[index];
}
istream& operator>>(istream& in,MyString &inString)
{
char temp[128];
delete [] inString.string;
in>>temp;
strcpy(inString.string,temp);
return in;
}
void MyString::read(istream &inString,char delimit)
{
char temp[128];
delete []string;
inString.getline(temp,127,delimit);
strcpy(string,temp);
}
MyString operator+(const MyString left,const MyString right)
{
MyString temp;
//temporary mystring to hold contents of left.string+right.string
temp.string = new char[strlen(left.string)+strlen(right.string)+1];
//dynamic array size of left.string+right.string+1
strcat(left.string,right.string);
//make left.string+right.string into left.string
strcpy(temp.string,left.string);
//copy the contents of left.string into temp.string;
return temp;
//return the copy of MyString temp
}
MyString& MyString :: operator+=(const MyString &right)
{
*this = *this+right;
return *this;
}
int MyString::length()const
{
return strlen(string);
}
bool operator<(const MyString &left, const MyString &right)
{
return strcmp(left.string,right.string) < 0;
}
bool operator<=(const MyString &left, const MyString &right)
{
return strcmp(left.string,right.string) <= 1;
}
bool operator>(const MyString &left, const MyString &right)
{
return strcmp(left.string,right.string) > 0;
}
bool operator>=(const MyString &left, const MyString &right)
{
return strcmp(left.string,right.string) >= 1;
}
bool operator==(const MyString &left, const MyString &right)
{
return strcmp(left.string,right.string) == 1;
}
bool operator!=(const MyString &left, const MyString &right)
{
return strcmp(left.string,right.string) != 1;
}
crahses (again). I fixed up all the things you guys said I should, except
for some which would not meet the project requiremnts. here is my code. it
compiles, but crashes winsioux.
#ifndef MYSTRING_H
#define MYSTRING_H
#include <iostream>
using namespace std;
class MyString {
public:
//Constructors, Copy, and Destrctors
MyString(); //one of four
MyString(const char *inString); //two of four
MyString operator=(const MyString right); //three of four
MyString(const MyString &right); //four of four
~MyString(); //destructor
//input/output
int length()const;
friend ostream& operator<<(ostream& out,const MyString &outString);
friend istream& operator>>(istream& in,MyString &inString);
void read(istream& inString,char delimit);
//Overloaded brackets
char& operator[](int index);
char operator[](int index)const;
friend MyString operator+(const MyString left,const MyString right);
MyString& operator+=( 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);
friend bool operator!=(const MyString &left, const MyString &right);
private:
char * string;
};
#endif
/*
* -------------------
* These functions are designed to help you test your MyString objects,
* as well as show the client usage of the class.
*
* The BasicTest function builds an array of strings using various
* constructor options and prints them out. It also uses the String
* stream operations to read some strings from a data file.
*
* The RelationTest function checks out the basic relational operations
* (==, !=, <, etc) on Strings and char *s.
*
* The ConcatTest functions checks the overloaded + and += operators that
* do string concatenation.
*
* The CopyTest tries out the copy constructor and assignment operators
* to make sure they do a true deep copy.
*
* Although not exhaustive, these tests will help you to exercise the basic
* functionality of the class and show you how a client might use it.
*
* While you are developing your MyString class, you might find it
* easier to comment out functions you are ready for, so that you don't
* get lots of compile/link complaints.
*/
#include "mystring.h"
#include <fstream>
#include <cctype> // for toupper()
#include <string> // for strchr(), strstr(), etc.
#include <cassert>
#include <iostream>
using namespace std;
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();
}
bool eof(istream& in)
{
char ch;
in >> ch;
in.putback(ch);
return !in;
}
void BasicTest()
{
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 << endl;
}
cout << endl << "----- Now reading MyStrings from file" << endl;
cout << endl << "----- first, word by word" << endl;
ifstream in("string.data");
assert(in);
while (!eof(in)) {
MyString s; // creates an empty string
if (in.peek() == '#') { // peek at char, comments start with #
in.ignore(128, '\n'); // skip this line, it's a comment
} else {
in >> s;
cout << "Read string = " << s << endl;
}
}
in.close();
cout << endl << "----- now, line by line" << endl;
ifstream in2("string.data");
assert(in2);
while (!eof(in2)) {
MyString s; // creates an empty string
if (in2.peek() == '#') { // peek at char, comments start with #
in2.ignore(128, '\n'); // skip this line, it's a comment
} else {
s.read(in2, '\n');
cout << "Read string = " << s << endl;
}
}
in2.close();
cout << endl << "----- Testing access to characters (using const)" <<
endl;
const MyString s("abcdefghijklmnopqsrtuvwxyz");
cout << "Whole string is " << s << endl;
cout << "now char by char: ";
for (int i = 0; i < s.length(); i++){
cout << s;
}
cout << endl << "----- Testing access to characters (using non-const)"
<< endl;
MyString s2("abcdefghijklmnopqsrtuvwxyz");
cout << "Start with " << s2;
for (int i = 0; i < s.length(); i++){
s2 = toupper(s2);
}
cout << " and convert to " << s2 << endl;
}
void RelationTest()
{
cout << "\n----- Testing relational operators between MyStrings\n";
const MyString strs[] =
{MyString("app"), MyString("apple"), MyString(""),
MyString("Banana"), MyString("Banana")};
for (int i = 0; i < 4; i++) {
cout << "Comparing " << strs << " to " << strs[i+1] << endl;
cout << "\tIs left < right? " << (strs < strs[i+1]) << endl;
cout << "\tIs left <= right? " << (strs <= strs[i+1]) << endl;
cout << "\tIs left > right? " << (strs > strs[i+1]) << endl;
cout << "\tIs left >= right? " << (strs >= strs[i+1]) << endl;
cout << "\tDoes left == right? " << (strs == strs[i+1]) << endl;
cout << "\tDoes left != right ? " << (strs != strs[i+1]) << endl;
}
cout << "\n----- Testing relations between MyStrings and char *\n";
MyString s("he");
const char *t = "hello";
cout << "Comparing " << s << " to " << t << endl;
cout << "\tIs left < right? " << (s < t) << endl;
cout << "\tIs left <= right? " << (s <= t) << endl;
cout << "\tIs left > right? " << (s > t) << endl;
cout << "\tIs left >= right? " << (s >= t) << endl;
cout << "\tDoes left == right? " << (s == t) << endl;
cout << "\tDoes left != right ? " << (s != t) << endl;
MyString u("wackity");
const char *v = "why";
cout << "Comparing " << v << " to " << u << endl;
cout << "\tIs left < right? " << (v < u) << endl;
cout << "\tIs left <= right? " << (v <= u) << endl;
cout << "\tIs left > right? " << (v > u) << endl;
cout << "\tIs left >= right? " << (v >= u) << endl;
cout << "\tDoes left == right? " << (v == u) << endl;
cout << "\tDoes left != right ? " << (v != u) << endl;
}
void ConcatTest()
{
cout << "\n----- Testing concatentation on MyStrings\n";
const MyString s[] =
{MyString("outrageous"), MyString("milk"), MyString(""),
MyString("cow"), MyString("bell")};
for (int i = 0; i < 4; i++) {
cout << s << " + " << s[i+1] << " = " << s + s[i+1] << endl;
}
cout << "\n----- Testing concatentation between MyString and char *\n";
const MyString a("abcde");
const char *b = "XYZ";
cout << a << " + " << b << " = " << a + b << endl;
cout << b << " + " << a << " = " << b + a << endl;
cout << "\n----- Testing shorthand concat/assign on MyStrings\n";
MyString s2[] =
{MyString("who"), MyString("what"), MyString("WHEN"),
MyString("Where"), MyString("why")};
for (int i = 0; i < 4; i++) {
cout << s2 << " += " << s2[i+1] << " = ";
cout << (s2 += s2[i+1]) << endl;
}
cout << "\n----- Testing shorthand concat/assign using char *\n";
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 << "\n----- Testing copy constructor and operator= on MyStrings\n";
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::MyString()
{
string = new char[0];
string[0] = 0;
}
MyString::MyString(const char *inString)
{
string = new char[strlen(inString)+1];
strcpy(string,inString);
}
MyString::~MyString()
{
delete []string;
}
ostream& operator<<(ostream &out,const MyString &outString)
{
out<<outString.string;
return out;
}
MyString MyString:: operator=(const MyString right)
{
if (this != &right)
{
delete []string;
string = new char[strlen(right.string)+1];
strcpy(string,right.string);
}
return *this;
}
MyString::MyString(const MyString &right)
{
string = new char[strlen(right.string)+1];
strcpy(string,right.string);
}
char& MyString:
{
assert(index>=0 && index < strlen(string));
return string[index];
}
char MyString:
{
assert(index>=0 && index < strlen(string));
return string[index];
}
istream& operator>>(istream& in,MyString &inString)
{
char temp[128];
delete [] inString.string;
in>>temp;
strcpy(inString.string,temp);
return in;
}
void MyString::read(istream &inString,char delimit)
{
char temp[128];
delete []string;
inString.getline(temp,127,delimit);
strcpy(string,temp);
}
MyString operator+(const MyString left,const MyString right)
{
MyString temp;
//temporary mystring to hold contents of left.string+right.string
temp.string = new char[strlen(left.string)+strlen(right.string)+1];
//dynamic array size of left.string+right.string+1
strcat(left.string,right.string);
//make left.string+right.string into left.string
strcpy(temp.string,left.string);
//copy the contents of left.string into temp.string;
return temp;
//return the copy of MyString temp
}
MyString& MyString :: operator+=(const MyString &right)
{
*this = *this+right;
return *this;
}
int MyString::length()const
{
return strlen(string);
}
bool operator<(const MyString &left, const MyString &right)
{
return strcmp(left.string,right.string) < 0;
}
bool operator<=(const MyString &left, const MyString &right)
{
return strcmp(left.string,right.string) <= 1;
}
bool operator>(const MyString &left, const MyString &right)
{
return strcmp(left.string,right.string) > 0;
}
bool operator>=(const MyString &left, const MyString &right)
{
return strcmp(left.string,right.string) >= 1;
}
bool operator==(const MyString &left, const MyString &right)
{
return strcmp(left.string,right.string) == 1;
}
bool operator!=(const MyString &left, const MyString &right)
{
return strcmp(left.string,right.string) != 1;
}