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

This is the problem http://www.cs.bu.edu/teaching/cpp/string/class/part2/ In a p

ID: 3539091 • Letter: T

Question

This is the problem

http://www.cs.bu.edu/teaching/cpp/string/class/part2/




In a previous lab, we discussed some categories of problems that occur with strings represented as simple arrays of characters:






Previously, we wrote a String class that addressed instances of two of those categories:

This time, we will augment our definition of the String class to address issues of static-ness, unnatural-ness and inconvenience.

We wish to allow our String class to accommodate strings of different sizes. To that end, instead of storing a string's characters in a fixed-size array:

we will store them using a pointer:

and allocate space for the array it points to:

With this design, we'll need to reallocate the array when its contents change. AND, we must remember to deallocate the memory once we are done with it.

We would like to use some of the basic operators with Strings. To do so, we will redefine methods that we wrote last time:

Usage:

Usage:

Usage:

Usage:

Usage:

Usage:


Note: Note that we return a reference to a String. That's so that we can return the String object we assigned to. Why? Well, C++ allows things like:

so we should allow the same for objects.

By default, we can assign one object to another of the same type. Why then, do we need to write our own assignment operator?

The default behavior for assignment is to assign each data member from one object to another. For objects containing a pointer, that doesn't always work as desired:

For Strings, the result after the default assignment operation is that the contents data member (the one that points to where the characters are stored) points to the same location, so that if we change str1 or str2 we end up affecting the other!

To avoid this, we must write our own operator =, which does the right thing.



Requires that a copy of a String be made.

Like assignment, the default behavior for copying is to copy the object by copying each data member. Since our String class contains a pointer, we'll have to write our own copy constructor:


Note: Passing a String by reference, e.g.,

works just fine, since no copy is made. Returning a String from a function works fine as well (see the operator = we will write).

It is reasonable to want to assign Strings from or compare Strings to both other String objects and arrays of characters:

It would be convenient to have methods that can deal with both. Rather than writing one method for each, e.g.:

we can simply write a constructor that converts an array of characters into a String object:

and then write all other methods in terms of String objects. Then, if we call a String method with an array of characters, the compiler will first call the conversion constructor to convert it to a String object, and then pass that temporary String object to the method:


You must write a String class that now addresses some aspect of all four categories of problems, and that provides some other basic String functionality.

Your new String class will have the following design (changes or additions from the previous version are in red):


The String class code must be put in its own module, i.e., a file mystring.h (the header file) should hold the class definition and a file mystring.cpp (the implementation file) should hold the method definitions.


Each String object should contain the following data as part of its internal representation:



The String class should provide the following methods for setting up, accessing and changing strings:




This is needed when a String is initialized with another String, is passed by value or is returned from a function.



Don't forget to deal with the case of self-assignment.






In your implementation of String's methods, you may use the library functions provided by string.h, which operate on arrays of characters terminated by nul's ().


The file String-test2.cpp provides a main program to test your new String class.


In order to demonstrate an understanding of this String class, you should be able to determine which of the above methods are called in the following pieces of code:







Problem Solution using a String class The error of accessing characters outside a string Make the String's data private and only allow access to the characters of the string via a method that does range-checking. The inefficient acquisition of a string's length Store the length of the string as an additional piece of data in the String class. Update that field every time the contents of the string is altered.

Explanation / Answer

// String.h


#include <iostream>

#include <string.h>

#include <stdlib.h>

#include <fstream>

using namespace std;


class String

{

private:

char *contents;

int lengths;

public:

String(){}

String(const char []);

String(const String &str);

String &operator =(const String &str);

String &operator =(const char str[]);

void append(const String &str);

char operator [](int i) const;

bool operator ==(const String &str) const;

bool operator !=(const String &str) const;

bool operator >(const String &str) const;

bool operator <(const String &str) const;

bool operator >=(const String &str) const;

bool operator <=(const String &str) const;

int length() const;

void print() const;

~String(){}


/* data */

};



//String.cpp


#include "String.h"



String :: String(const char str[])

{

lengths = strlen(str);

contents = new char [lengths];

strcpy(contents,str);

}


String :: String(const String &str)

{


*this = str;

}


String & String ::operator =(const String &str)

{

lengths = str.length();

contents = new char [lengths];

for(int i=0;i<lengths;i++)

contents[i] = str[i];

return *this;

}


String & String :: operator =(const char str[])

{

*this = String(str);

}

void String :: append(const String &str)

{

char *temp = new char [lengths+str.length()];

strcpy(temp,contents);

int size;

for(size=0;str[size];size++);

for(int i=0;i<=str.length();i++)

temp[i+lengths] = str[i];

contents = temp;

}


char String :: operator [](int i) const

{

if(i>=lengths||i<0)

{

cout<<"Out of bounds"<<endl;

return 0;

}

return contents[i];


}


bool String::operator ==(const String &str) const

{

char temp[str.length()];

for(int i =0;i<str.length();i++)

temp[i] = str[i];

return strcmp(contents, temp) == 0;

}


bool String::operator !=(const String &str) const

{

char temp[str.length()];

for(int i =0;i<str.length();i++)

temp[i] = str[i];

return strcmp(contents, temp) != 0;

}


bool String :: operator >(const String &str) const

{

char temp[str.length()];

for(int i =0;i<str.length();i++)

temp[i] = str[i];

return strcmp(contents, temp) > 0;

}


bool String :: operator <(const String &str) const

{

char temp[str.length()];

for(int i =0;i<str.length();i++)

temp[i] = str[i];

return strcmp(contents, temp) < 0;

}


bool String::operator >=(const String &str) const

{

char temp[str.length()];

for(int i =0;i<str.length();i++)

temp[i] = str[i];

return strcmp(contents, temp) >= 0;

}

bool String::operator <=(const String &str) const

{

char temp[str.length()];

for(int i =0;i<str.length();i++)

temp[i] = str[i];

return strcmp(contents, temp) <= 0;

}


void String :: print() const

{

cout << contents;

}


int String :: length() const

{

return lengths;

}


// main.cpp


#include "String.h"


int main()

{

String str1;

String str2 = "abc", str3("def");

str1 = str2;

str3 = "value"; // More than one here!

cout <<str1[3];

String str4 = str3;

}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote