In: Computer Science
Using the following code write the following instructions in C++
Implementation:
1. Re-implement your String class to use a dynamically allocated array for storage. It will be a NULL terminating charater array.
2. This dynamic version of the String will only allocate exactly the amount of memory necessary to store the characters. That is, the length will be the same as the capacity. However, the size of the dynamic array needs to have an extra char for the NULL terminator.
3. To re-write the constructors to allocate the correct amount of memory.
4. The default constructor allocates an array of size 1 for the empty string. The other constructors will allocate memory as needed. For example for String str("abc"); str.capacity() == 3, str.length() == 3, and str.string_size == 4.
5. Implement a destructor, copy constructor, constant time swap, and assignment operator for your ADT.
6. You will need to re-implement capacity(). length() remains the same.
7. You will also have to update concat and += to return the proper sized string result.
8. Implement the private constructors String(int) and
String(int, const char *).
String(int) constructs the object as the emptry string with int
capacity.
String(int, const char *) works the same as String(const char *)
but allocates int capacity.
9. Implement a private method reset_capacity to change the capacity of your string while keeping the contents intact. That is, create a new array and copy contents over to the new array, making sure to clean up memory.
10. The private constructors and method may be useful for re-implementing + and +=.
Testing:
11. Write tests for the methods developed for this project.
12. Write test cases first. Testing must be thorough. You will be relying on the String to be correct.
13. You should make sure that the test cases you develop are very complete.
14. The otests test the constructors, assignment, copy, +, ==, and <.
15. If you add additional member variables the tests will not work properly.
--------------------------------------------------------------------------------
string.hpp
--------------------------------------------------------------------------------
#ifndef STRING_HPP #define STRING_HPP #include <iostream> /** * @invariant str[length()] == 0 * && length() == capacity() * && capacity() == stringSize - 1 */ class String { private: // helper constructors and methods String(int); String(int, const char *); void reset_capacity (int); char * str; // size includes NULL terminator int string_size; public: // constructor: empty string, String('x'), and String("abcd") String(); String(char); String(const char *); // copy ctor, destructor, constant time swap, and assignment String(const String &); ~String(); void swap (String &); String & operator= (String); // subscript: accessor/modifier and accessor char & operator[](int); char operator[](int) const; // max chars that can be stored (not including null terminator) int capacity() const; // number of char in string int length () const; // concatenation String operator+ (const String &) const; String & operator+=(String); // relational methods bool operator==(const String &) const; bool operator< (const String &) const; // i/o friend std::ostream& operator<<(std::ostream &, const String &); friend std::istream& operator>>(std::istream &, String &); }; // free functios for concatenation and relational String operator+ (const char *, const String &); String operator+ (char, const String &); bool operator== (const char *, const String &); bool operator== (char, const String &); bool operator< (const char *, const String &); bool operator< (char, const String &); bool operator<= (const String &, const String &); bool operator!= (const String &, const String &); bool operator>= (const String &, const String &); bool operator> (const String &, const String &); #endif
---------------------------------------------------------------------------------------------------------------------------
string.cpp
---------------------------------------------------------------------------------------------------------------------------
#include <iostream> #include <cassert> #include "string.hpp" String::String(){ str[0] = 0; } String::String(char ch){ str[0] = ch; str[1] = 0; } String::String(const char* s){ int pos = 0; while(s[pos] != 0){ str[pos] = s[pos]; ++pos; if(pos >= capacity()) break; } str[pos] = 0; } int String::length() const{ int size = 0; while(str[size] != 0) ++size; return size; } int String::capacity() const{ return STRING_SIZE -1; } char& String::operator[](int i){ assert(i >= 0); assert(i <= length()); return str[i]; } void String::swap(String& str1){ int tempStr = string_size; string_size = str1.string_size; str1.string_size = tempStr; int* tempStr1 = str; str = str1.str; str1.str = tempStr1; } char String::operator[](int i) const{ assert(i >= 0); assert(i <= length()); return str[i]; } bool String::operator==(const String& rhs) const{ int pos = 0; while(str[pos] != 0 && str[pos] == rhs.str[pos]){ ++pos; } return str[pos] == rhs.str[pos]; } std::istream& operator>>(std::istream& in, String& rhs){ in >> rhs.str; return in; } std::ostream& operator<<(std::ostream& out, const String& rhs){ out << rhs.str; return out; } bool String::operator<(const String& rhs) const{ int pos = 0; while(str[pos] != 0 && rhs.str[pos] != 0 && str[pos] == rhs.str[pos]){ ++pos; } return str[pos] < rhs.str[pos]; } String String::operator+(const String& rhs) const{ String result(str); int offset = length(); int pos = 0; while(rhs.str[pos] != 0){ result.str[offset + pos] = rhs.str[pos]; ++pos; } result.str[offset + pos] = 0; return result; } String& String::operator+=(String rhs){ int offset = length(); int pos = 0; while(rhs.str[pos] != 0){ if((offset + pos) >= capacity()) break; str[offset + pos] = rhs.str[pos]; ++pos; } str[offset + pos] = 0; return *this; } String operator+(const char charArray[], const String& rhs){ return rhs + charArray; } String operator+(char s, const String& rhs){ return s + rhs; } bool operator==(const char charArray[], const String& rhs){ if(charArray == rhs){ return true; } else{ return false; } } bool operator==(char s, const String& rhs){ if(s == rhs){ return true; } else{ return false; } } bool operator<(const char charArray[], const String& rhs){ if(charArray < rhs){ return true; } else{ return false; } } bool operator<(char s, const String& rhs){ if(s < rhs){ return true; } else{ return false; } } bool operator<=(const String& lhs, const String& rhs){ if(lhs < rhs || lhs == rhs){ return true; } else{ return false; } } bool operator!=(const String& lhs, const String& rhs){ if(lhs.length() != rhs.length()){ return true; } int pos = 0; while(lhs[pos] != rhs[pos]){ pos++; } if(pos == lhs.length()){ return true; } return false; } bool operator>=(const String& lhs, const String& rhs){ if(lhs > rhs || lhs == rhs) { return true; } else{ return false; } } bool operator>(const String& lhs, const String& rhs){ if(!(lhs <= rhs)){ return true; } else{ return false; } }
Output:
Programs:
--------------------------------------------------------------------------------
string.hpp
--------------------------------------------------------------------------------
#ifndef STRING_HPP
#define STRING_HPP
#include <iostream>
/**
* @invariant str[length()] == 0
* && length() == capacity()
* && capacity() == stringSize - 1
*/
class String {
private:
// helper constructors and methods
String(int);
String(int, const char *);
void reset_capacity (int);
char * str;
// size includes NULL terminator
int STRING_SIZE;
public:
// constructor: empty string, String('x'), and
String("abcd")
String();
String(char);
String(const char *);
// copy ctor, destructor, constant time swap, and
assignment
String(const String &);
//~String();
void swap (String &);
String & operator= (String);
// subscript: accessor/modifier and accessor
char & operator[](int);
char operator[](int) const;
// max chars that can be stored (not including null
terminator)
int capacity() const;
// number of char in string
int length () const;
// concatenation
String operator+ (const String &) const;
String & operator+=(String);
// relational methods
bool operator==(const String &) const;
bool operator< (const String &) const;
// i/o
friend std::ostream& operator<<(std::ostream &, const
String &);
friend std::istream& operator>>(std::istream &,
String &);
};
// free functios for concatenation and relational
String operator+ (const char *, const String &);
String operator+ (char, const String &);
bool operator== (const char *, const String &);
bool operator== (char, const String &);
bool operator< (const char *, const String &);
bool operator< (char, const String &);
bool operator<= (const String &, const String &);
bool operator!= (const String &, const String &);
bool operator>= (const String &, const String &);
bool operator> (const String &, const String &);
#endif
---------------------------------------------------------------------------------------------------------------------------
string.cpp
---------------------------------------------------------------------------------------------------------------------------
#include <iostream>
#include <cstring>
#include <cassert>
#include "string.hpp"
//private constructors impementation
// // helper constructors and methods
String::String(int)
{
STRING_SIZE=0;
}
String::String(int c, const char *s)
{
int pos = 0;
while(s[pos] != '\0')
{
str[pos] = s[pos];
++pos;
}
str[pos] = '\0';
STRING_SIZE=pos;
}
void String::reset_capacity(int s)
{
STRING_SIZE=s;
}
//// constructor: empty string, String('x'), and
String("abcd")
String::String(){
str = NULL;
}
String::String(char ch){
str[0] = ch;
str[1] = '\0';
}
String::String(const char* chars){
STRING_SIZE = strlen(chars)+1 ;
str = new char[STRING_SIZE];
for(int i = 0; i < STRING_SIZE-1; i++)
{
str[i] = chars[i];
}
str[STRING_SIZE-1] = '\0';
}
//// copy ctor, destructor, constant time swap, and
assignment
String::String(const String &s)
{
STRING_SIZE=s.length();
str=s.str;
}
// number of char in string
int String::length() const{
int size = 0;
while(str[size] != '\0')
++size;
return size;
}
// max chars that can be stored (not including null
terminator)
int String::capacity() const{
return STRING_SIZE-1;
}
// subscript: accessor/modifier and accessor
char& String::operator[](int i){
assert(i >= 0);
assert(i <= length());
return str[i];
}
void String::swap(String& str1){
int tempStr = STRING_SIZE;
STRING_SIZE = str1.STRING_SIZE;
str1.STRING_SIZE = tempStr;
char* tempStr1 = str;
str = str1.str;
str1.str = tempStr1;
}
char String::operator[](int i) const{
assert(i >= 0);
assert(i <= length());
return str[i];
}
// relational methods
bool String::operator==(const String& rhs) const{
int pos = 0;
while(str[pos] != '\0' && str[pos] == rhs.str[pos]){
++pos;
}
return str[pos] == rhs.str[pos];
}
// i/o
std::istream& operator>>(std::istream& in,
String& rhs){
in >> rhs.str;
return in;
}
std::ostream& operator<<(std::ostream& out, const
String& rhs){
out << rhs.str;
return out;
}
// relational methods
bool String::operator<(const String& rhs) const{
int pos = 0;
while(str[pos] != '\0' && rhs.str[pos] != '\0' &&
str[pos] == rhs.str[pos]){
++pos;
}
return str[pos] < rhs.str[pos];
}
// free functios for concatenation and relational
String String::operator+(const String& rhs) const{
String result(str);
int offset = length();
int pos = 0;
// concatenation
while(rhs.str[pos] != '\0'){
result.str[offset + pos] = rhs.str[pos];
++pos;
}
result.str[offset + pos] = 0;
return result;
}
String& String::operator+=(String rhs){
int offset = length();
int pos = 0;
while(rhs.str[pos] != '\0'){
str[offset ++] = rhs.str[pos];
++pos;
}
str[offset++] = '\0';
reset_capacity(offset);
return *this;
}
String operator+(const char charArray[], const String&
rhs){
String s(charArray);
return rhs + s ;
}
String operator+(char s, const String& rhs){
return s + rhs;
}
bool operator==(const char charArray[], const String&
rhs){
if(charArray == rhs){
return true;
}
else{
return false;
}
}
bool operator==(char s, const String& rhs){
if(s == rhs){
return true;
}
else{
return false;
}
}
bool operator<(const char charArray[], const String&
rhs){
if(charArray < rhs){
return true;
}
else{
return false;
}
}
bool operator<(char s, const String& rhs){
if(s < rhs){
return true;
}
else{
return false;
}
}
bool operator<=(const String& lhs, const String&
rhs){
if(lhs < rhs || lhs == rhs){
return true;
}
else{
return false;
}
}
bool operator!=(const String& lhs, const String&
rhs){
if(lhs.length() != rhs.length()){
return true;
}
int pos = 0;
while(lhs[pos] != rhs[pos]){
pos++;
}
if(pos == lhs.length()){
return true;
}
return false;
}
bool operator>=(const String& lhs, const String&
rhs){
if(lhs > rhs || lhs == rhs) {
return true;
}
else{
return false;
}
}
bool operator>(const String& lhs, const String&
rhs){
if(!(lhs <= rhs)){
return true;
}
else{
return false;
}
}
---------------------------------------------------------------------------------------------------------------------------
stringTest.cpp
---------------------------------------------------------------------------------------------------------------------------
#include <iostream>
#include <cstring>
#include <fstream>
#include <cstdlib>
#include "string.cpp"
using namespace std;
void test_copy_and_destructor(String S);
int main()
{
String string1("hai,Hello");
cout<<"First string: "<<string1<<
endl;
String string2("welcome");
cout<<"First string: "<<string1<<
endl;
cout<<"Second string: "<<string2<<
endl;
cout << "\n Copy first string to third string" << endl;
String string3(string1);//copy constructor
cout << "third string: " << string3 << endl;
//Concatenation of two strings
cout << "\nConcatenation using operator + "
<< endl;
String string4=string1 + string2;
cout << "string1 + string2: " <<
string4<< endl;
//print each charcter in string
cout << "\noperators [ ] " << endl;
for (int i = 0; i < string2.length(); i++)
cout << string2[i] << "
";
cout << endl;
//operators += , ==, != between two strings
cout << "\noperators += , ==, != " << endl;
string2 += string1;
cout<<"st2 += st1: "<<string2<<
endl;
if (string3 == string1)
cout << "string3 and string1
are identical " << endl;
else
cout << "string3 and string1
are not identical " << endl;
if (string2 != string1)
cout << "string2 and string1
are not identical " << endl;
else
cout << "string2 and string1
are identical " << endl;
cout << "\noperators < " << endl;
if (string2 < string1)
cout << "string2 < string1
" << endl;
else cout << "string2 is not less than string1 "
<< endl;
return 0;
}
void test_copy_and_destructor(String S)
{
cout << "test: copy constructor and destructor
calls: " << endl;
String temp = S;
cout << "temp inside function
test_copy_and_destructor: " << temp << endl;
}