Question

Objectives You will implement and test a class called MyString. Each MyString object keeps track ...

Objectives

You will implement and test a class called MyString. Each MyString object keeps track of a sequence of characters, similar to the standard C++ string class but with fewer operations. The objectives of this programming assignment are as follows.

  • Ensure that you can write a class that uses dynamic memory to store a sequence whose length is unspecified. (Keep in mind that if you were actually writing a program that needs a string, you would use the C++ standard string class, so this is mostly a learning experience to teach yourself the kind of things that go on in the implementation of the C++ standard string class.)
  • Continue to practice incremental development and testing of your classes.

Problem Description

In this programming assignment, you will implement a new class called MyString, using a header file (most of which is written for you) and an implementation file (which you will write by yourself). The string that you implement is consistent with the C++ standard library string class (but with fewer operations). You are to write the following files:

  1. MyString.h: The header file for the MyString class. Actually, you don't have to write much of this file. Just start with the given MyString.h file (available on Blackboard) and add your name and other information at the top, and then fill in the necessary information. If some of your member functions are implemented as inline functions, then you may put those implementations in this file too.
  2. MyString.cpp: The implementation file for the MyString class. You will write all of this file, which will have the implementations of all the MyString's member functions.

In the development of this program, you may use functions from the #include facility such as strlen, strcpy, strcat, strcmp, and so on (an introduction to C-strings is available as a Supplementary Reading on Blackboard under Content). Do NOT use the built-in C++ standard string class at any point in your implementation. Your member functions must NOT write any output to cout, nor expect any input from cin. All the interaction with the member functions should occur through their parameters.

You are to implement and test the following operations for the MyString class. The precondition/postcondition contract for all the MyString’s member functions is specified in the given header file.

  • A constructor.
  • An overloaded copy constructor.
  • A destructor.
  • The getLength member function.
  • The operator [].
  • The reserve function.
  • The assignment operator.
  • Three different versions of the operator +=.
  • The operator + (as a friend function).
  • The six comparison operators (as friend functions).
  • The operator << (as a friend function).
  • The operator >> (as a friend function).
  • The getline function (as a friend function).

Additional Requirements and Hints

The Private Member Variables

Carefully read the class definition in MyString.h. The MyString has a private member sequence to store the string as a null-terminated dynamic character array (so sequence is a pointer to char), and has a private member allocated to keep track of the total number of bytes allocated for the dynamic character array (each character takes one byte).

Notice here allocated is of type size_t. In C++, size_t is defined as an unsigned int type. Using size_t rather than unsigned int for string length leads to better portability of the code on different computer platforms. Also note that the total number of characters prior to the null character in sequence should always be less than allocated. We do not need to define a variable to hold the actual length of the string in sequence (i.e., the number of characters before the null character) since we may directly use the strlen function to obtain it.

The reserve Function

Programmers who use our string class never need to activate reserve, but they may wish to, for better efficiency. Our own implementations of other member functions (except for the constructors) can also activate reserve whenever a larger array is needed. When a member function activates reserve, the activation should occur before any other changes are made to the string. This follows the programming guideline of allocating new memory before changing an object. When reserving memory locations, you must make sure that you allow room for the null terminator. In the implementation of the reserve function, when new memory locations are reserved to hold the string, do not forget to deallocate the currently allocated memory locations.

The operator <<, >>, and getline Functions

In the implementation of the operator <<, >>, and getline functions, you may use the ostream operator <<, the istream operator >>, the isspace, and the istream peek, ignore, and get functions. The following is some hints.

The operator >> begins by skipping any white space in the input stream. (All the standard operators in C++ start by skipping white spaces.) After skipping the initial white spaces, our string input operator reads a string – reading up to but not including the next white space character (or until the input stream fails, which might occur from several causes, such as reaching the end of the file). The function isspace from library facility can help. This function has one argument (a character); it returns true if its argument is one of the white space characters. With this in mind, we can skip any initial white space with this loop:

// peek returns next char to be read without actually reading it.

while ( ins && isspace(ins.peek()) )

       ins.ignore(); // ignore the next character

The loop also uses three istream features:

  1. In a Boolean expression, the name of the istream (which is ins here) acts as a test of whether the input stream has failed. If ins results in a true value, then the stream is OK; a false value indicates a failure.
  2. The peek member function returns the next character to be read (without actually reading it).
  3. The ignore member function reads and discards the next character.

After skipping the initial white spaces, your implementation should set the string to be an empty string, and then read the input characters one at a time, adding each character to the end of the string. The reading stops when you reach more white space (or the end of file).

Once the target string (i.e., the MyString instance to receive the input) reaches its current capacity, our approach continues to work correctly, although it is inefficient because target is probably resized by the += operator each time that we add another character. Your comments in the program should warn programmers of this inefficiency so that a programmer can explicitly resize the target before calling the input operator.

For the getline function, you may also want to read one character at a time. You may use the following istream member function get in your program.

istream& get ( char& c ); // Extracts a character from the

                          // stream and stores it in c.

Check Preconditions

Your implementations should check preconditions of all functions. If the preconditions are not satisfied, you may simply terminate the program. Of course, if you want to write a more robust program, a better way to handle the violation of preconditions is to use try … catch … statements (see the corresponding Supplementary Reading available on Blackboard).

Input and Output

Your implementations must NOT produce any output to cout, nor expect any input from cin. All the interaction with the member functions occurs through their parameters.

Implement and Test Small Pieces

Don't tackle the whole project all at once. Start by implementing what you can, using one or several member functions together with a simple test driver client program to test the functionality of the functions.

MyString.h

#ifndef MYSTRING_H
#define MYSTRING_H
#include
#include // Provides size_t
using namespace std;

// Some compilers require that we prototype the << and >> operator functions
// outside the class. For this reason, we have added the following 3 lines to the
// MyString.h class specificaiton file.
class MyString; // Forward Declaration
ostream& operator <<(ostream&, const MyString&);
istream& operator >>(istream&, MyString&);

class MyString
{
public:
   // CONSTRUCTORS and DESTRUCTOR
   MyString(const char str[ ] = "");
   MyString(const MyString& source); // This is the copy constructor
   ~MyString( );
  
   // CONSTANT MEMBER FUNCTIONS
size_t getLength( ) const;
   char& operator[](size_t position) const;

   // MODIFICATION MEMBER FUNCTIONS
   void reserve(size_t n);
   const MyString& operator =(const MyString& source);
   void operator +=(const MyString& addend);
   void operator +=(const char addend[]);
   void operator +=(char addend);
  
   // FRIEND FUNCTIONS
   friend MyString operator +(const MyString& addend1, const MyString& addend2);
   friend bool operator ==(const MyString& s1, const MyString& s2);
   friend bool operator !=(const MyString& s1, const MyString& s2);
   friend bool operator >=(const MyString& s1, const MyString& s2);
   friend bool operator <=(const MyString& s1, const MyString& s2);
   friend bool operator > (const MyString& s1, const MyString& s2);
   friend bool operator < (const MyString& s1, const MyString& s2);
   friend ostream& operator <<(ostream& outs, const MyString& source);
   friend istream& operator >>(istream& ins, MyString& target);
   friend istream& getline(istream& ins, MyString& target);
  
private:
   char *sequence;
   size_t allocated; // size_t is defined as an unsigned int type. Using size_t
       // rather than unsigned int for string length leads to
       // better portability of the code.
};

#endif

0 0
Add a comment Improve this question Transcribed image text
Answer #1

Code Implemented

MyString::~MyString()
{
   if (sequence)
   {
       delete[] sequence;
       sequence = nullptr;
   }
}
MyString::MyString(const char str[])
{
   int index = 0;
   while (str[index] != '\0')
   {
       index++;
   }

   if (!sequence)
   {
       sequence = new char[index + 1];
   }
   strcpy_s(sequence, index + 1, str);
   allocated = index + 1;
}

MyString::MyString(const MyString& source)
{
   this->allocated = source.allocated;
  
   sequence = new char[this->allocated];
   strcpy_s(sequence, this->allocated, source.sequence);
}

size_t MyString::getLength() const
{
   return this->allocated - 1;
}

char& MyString::operator[](size_t position) const
{
   return this->sequence[position];
}

void MyString::reserve(size_t n)
{
   sequence = (char*)realloc(sequence, n);
}

const MyString& MyString::operator =(const MyString& source)
{
   this->allocated = source.allocated;
   if (sequence)
   {
       delete[] sequence;
       sequence = nullptr;
   }
   sequence = new char[source.allocated];
   strcpy_s(sequence, this->allocated, source.sequence);
   return *this;
}
void MyString::operator +=(const MyString& addend)
{
   this->sequence = (char*)realloc(this->sequence, (this->allocated + addend.allocated + 1));
   size_t i = 0;
   for (; i < addend.allocated; i++)
   {
       this->sequence[this->allocated + i - 1] = addend.sequence[i];
   }
   this->sequence[this->allocated + i] = '\0';
   this->allocated += addend.allocated;
}
void MyString::operator +=(const char addend[])
{
   int index = 0;
   while (addend[index] != '\0')
   {
       index++;
   }

   this->sequence = (char*)realloc(this->sequence, this->allocated + index + 2);
   size_t i = 0;
   for (; i < (index + 1); i++)
   {
       this->sequence[this->allocated + i - 1] = addend[i];
   }
   this->sequence[this->allocated + i] = '\0';
   this->allocated += (index + 1);

}
void MyString::operator +=(char addend)
{
   this->sequence = (char*)realloc(this->sequence, this->allocated + 2);
   this->sequence[this->allocated - 1] = addend;
   this->sequence[this->allocated] = '\0';
}

MyString operator +(const MyString& addend1, const MyString& addend2)
{
   MyString aString;

   aString.sequence = new char[addend1.allocated + addend2.allocated];
   aString.allocated = addend1.allocated + addend2.allocated;

   int index = 0;

   while (addend1.sequence[index] != '\0')
   {
       aString.sequence[index] = addend1[index];
       index++;
   }

   int count = 0;

   while (addend2.sequence[count] != '\0')
   {
       aString.sequence[index] = addend2[count];
       index++;
       count++;
   }

   aString.sequence[index] = '\0';
   return aString;
}

bool operator ==(const MyString& s1, const MyString& s2)
{
   if ((strcmp(s1.sequence, s2.sequence) == 0) && (s1.allocated == s2.allocated))
   {
       return true;
   }
   return false;
}

bool operator !=(const MyString& s1, const MyString& s2)
{
   if ((strcmp(s1.sequence, s2.sequence) != 0) || (s1.allocated != s2.allocated))
   {
       return true;
   }
   return false;
}

bool operator >=(const MyString& s1, const MyString& s2)
{
   if ((strcmp(s1.sequence, s2.sequence) >= 0))
   {
       return true;
   }
   return false;
}

bool operator <=(const MyString& s1, const MyString& s2)
{
   if ((strcmp(s1.sequence, s2.sequence) <= 0))
   {
       return true;
   }
   return false;
}

bool operator > (const MyString& s1, const MyString& s2)
{
   if ((strcmp(s1.sequence, s2.sequence) > 0))
   {
       return true;
   }
   return false;
}

bool operator < (const MyString& s1, const MyString& s2)
{
   if ((strcmp(s1.sequence, s2.sequence) < 0))
   {
       return true;
   }
   return false;
}

ostream& operator <<(ostream& outs, const MyString& source)
{
   outs << source.sequence;
   return outs;
}

istream& operator >>(istream& ins, MyString& target)
{
   char tempString[20];
   gets_s(tempString, 20);
   target.sequence = (char*)realloc(target.sequence, strlen(tempString) + 1);
   strcpy_s(target.sequence, strlen(tempString) + 1, tempString);
   target.allocated = strlen(tempString) + 1;
   return ins;
}

istream& getline(istream& ins, MyString& target)
{
   ins.getline(target.sequence, target.allocated);
   return ins;
}

Add a comment
Know the answer?
Add Answer to:
Objectives You will implement and test a class called MyString. Each MyString object keeps track ...
Your Answer:

Post as a guest

Your Name:

What's your source?

Earn Coins

Coins can be redeemed for fabulous gifts.

Not the answer you're looking for? Ask your own homework help question. Our experts will answer your question WITHIN MINUTES for Free.
Similar Homework Help Questions
  • You are to implement a MyString class which is our own limited implementation of the std::string...

    You are to implement a MyString class which is our own limited implementation of the std::string Header file and test (main) file are given in below, code for mystring.cpp. Here is header file mystring.h /* MyString class */ #ifndef MyString_H #define MyString_H #include <iostream> using namespace std; class MyString { private:    char* str;    int len; public:    MyString();    MyString(const char* s);    MyString(MyString& s);    ~MyString();    friend ostream& operator <<(ostream& os, MyString& s); // Prints string    MyString& operator=(MyString& s); //Copy assignment    MyString& operator+(MyString&...

  • Write a MyString class that stores a (null-terminated) char* and a length and implements all of...

    Write a MyString class that stores a (null-terminated) char* and a length and implements all of the member functions below. Default constructor: empty string const char* constructor: initializes data members appropriately Copy constructor: prints "Copy constructor" and endl in addition to making a copy Move constructor: prints "Move constructor" and endl in addition to moving data Copy assignment operator: prints "Copy assignment" and endl in addition to making a copy Move assignment operator: prints "Move assignment" and endl in addition...

  • C++ Write a MyString class that stores a (null-terminated) char* and a length and implements all...

    C++ Write a MyString class that stores a (null-terminated) char* and a length and implements all of the member functions below. Submit your completed source (.cpp) file. Default constructor: empty string const char* constructor: initializes data members appropriately Copy constructor: prints "Copy constructor" and endl in addition to making a copy Move constructor: prints "Move constructor" and endl in addition to moving data Copy assignment operator: prints "Copy assignment" and endl in addition to making a copy Move assignment operator:...

  • Please Implement ParkingLot.cpp below based off the completed Automobile Class and ClaimCheck class down below. Automobile.hpp...

    Please Implement ParkingLot.cpp below based off the completed Automobile Class and ClaimCheck class down below. Automobile.hpp #pragma once #include <iostream> #include <string> class Automobile { friend bool operator==( const Automobile& lhs, const Automobile& rhs ); friend std::ostream & operator<<( std::ostream& stream, const Automobile& vehicle ); private: std::string color_; std::string brand_; std::string model_; std::string plateNumber_; public: Automobile( const std::string & color, const std::string & brand, const std::string & model, const std::string & plateNumber ); }; bool operator!=( const Automobile& lhs, const...

  • 17. Write a non-member function called centroid(param) that takes a static array of points and the...

    17. Write a non-member function called centroid(param) that takes a static array of points and the size of the array and return the centroid of the array of points. If there is no center, return the origins private: double x, y, z public: /Constructors Point(); Point(double inX, double inY, double inZ = 0); Point(const Point& inPt); / Get Functions double getX() const; double getY) const; double getZ) const; Set Functions void setX(double inX); void setY(double inY); void setZ(double inZ); void...

  • 2. (50 marks) A string in C++ is simply an array of characters with the null...

    2. (50 marks) A string in C++ is simply an array of characters with the null character(\0) used to mark the end of the string. C++ provides a set of string handling function in <string.h> as well as I/O functions in <iostream>. With the addition of the STL (Standard Template Library), C++ now provides a string class. But for this assignment, you are to develop your own string class. This will give you a chance to develop and work with...

  • C++ project we need to create a class for Book and Warehouse using Book.h and Warehouse.h header ...

    C++ project we need to create a class for Book and Warehouse using Book.h and Warehouse.h header files given. Then make a main program using Book and Warehouse to read data from book.dat and have functions to list and find book by isbn Objectives: Class Association and operator overloading This project is a continuation from Project 1. The program should accept the same input data file and support the same list and find operations. You will change the implementation of...

  • 12.24 HW2: Practice with Classes Objectives: Become familiar with developing a C++ class, to include developing:...

    12.24 HW2: Practice with Classes Objectives: Become familiar with developing a C++ class, to include developing: A constructor An multiplication operator A friend function (input operator) Introduce various C and C++ functions for parsing user input Assignment Details This assignment consists of 6 parts. Part 1: Using an IDE of your own choosing (Visual Studio is recommended), create a new project and copy the starter code ComplexNumber.h ComplexNumber.cpp and TestComplexNumber.cpp to this new project for developing and testing your solution....

  • Use a B-Tree to implement the set.h class. #ifndef MAIN_SAVITCH_SET_H #define MAIN_SAVITCH_SET_H #include <cstdlib> // Provides...

    Use a B-Tree to implement the set.h class. #ifndef MAIN_SAVITCH_SET_H #define MAIN_SAVITCH_SET_H #include <cstdlib> // Provides size_t namespace main_savitch_11 { template <class Item> class set { public: // TYPEDEFS typedef Item value_type; // CONSTRUCTORS and DESTRUCTOR set( ); set(const set& source); ~set( ) { clear( ); } // MODIFICATION MEMBER FUNCTIONS void operator =(const set& source); void clear( ); bool insert(const Item& entry); std::size_t erase(const Item& target); // CONSTANT MEMBER FUNCTIONS std::size_t count(const Item& target) const; bool empty( ) const...

  • choices: supporting function default constructor friend function static member class getter setter attribute assignment operator Identify...

    choices: supporting function default constructor friend function static member class getter setter attribute assignment operator Identify the parts of the following class definition: class Student { string name; const int ID; float gpa; const char gender; public: Student(); Student& operator (const Student&); string getName() const {return name; } friend ostream& operator<<(ostream&, const Student); }; void outputStudent (const Student&); name [Choose Student) [Choose operator Choose) outputStudent Choose operator<< Choose) getNamel) [Choose

ADVERTISEMENT
Free Homework Help App
Download From Google Play
Scan Your Homework
to Get Instant Free Answers
Need Online Homework Help?
Ask a Question
Get Answers For Free
Most questions answered within 3 hours.
ADVERTISEMENT
ADVERTISEMENT