Question

In: Computer Science

c++ I cannot get my operator+ to pass my test, it is failing on the first...

c++

I cannot get my operator+ to pass my test, it is failing on the first test, how would i convert my operator+ to use pointers and dynamic memory?

Requirements:

  • You CANNOT use the C++ standard string or any other libraries for this assignment, except where specified.
  • You must use your ADT string for the later parts of the assignment.
  • using namespace std; is stricly forbiden. As are any global using statements.
  • Name the folder for this project: string (please use all lower case letters).
  • Milestone 1
    • Implementation:
      • Create an ADT String using the class construct. It will be a NULL (zero) terminating charater array.
      • Note: C++ has a standard type called string so you should not use this name. Use String instead.
      • Please name all your files using only lower case letters.
      • Use the provided specification (svn/shared/project2/string-mile1.hpp) for naming your class and methods You should rename this to string.hpp. A test suite will be provided in Part 2 that uses this interface to test your string class.
      • You should use a fixed sized array of char for storage with a max capacity based on a constant const int STRING_SIZE = 256; This array will store the characters along with the NULL (0) terminator.
      • Implement the constructor functions (i.e., for char[] and char).
      • Overload + and += as concatenation (make sure they works for all variations string + string, string + char[], char[] + string, etc).
      • Overload all the relational operators (==, <, >, etc.).
      • Implement the methods:
        • operator[](int) - both accessor and modifier versions
        • length() - returns number of characters in string
        • capacity() - returns the max number of characters that can be stored in the string
        • substr(int start, int end) - returns the sub string from start to end position (inclusive)
        • findch(int pos, char ch) - returns location of ch at or after pos, returns -1 if not found
        • findstr(int pos, cosnt String& str) - returns the location of str at or after pos, returns -1 if not found.
        • Overload both I/O operators - Input should read in one word at a time. The input operator for char[] works that way and can be used.
    • Testing:
      • Develop a set of test cases, using asserts, for each of the operators and methods of the String class.
      • Write test cases first. Testing must be thorough. You will be relying on the string to be correct.
      • The command make tests will build and run the unit tests.
      • After each function passes a test, commit your work to svn with a message such as "Constructor tests passed".
      • Your string class will be tested on a set of cases developed by the instructors. You will be graded on how well you pass the instructor tests. These tests cover the required constructors and operators.
  • Milestone 2
    • Implementation:
      • Re-implement your String class to use a dynamically allocated array for storage. Just as in the previous version, it will be a NULL terminating charater array.
      • Use the provided specification (svn/shared/project2/string-mile2.hpp) for naming your class and methods You should rename this to string.hpp.
      • This dynamic version of the String will only allocate exactly the amount of memory necessary to store the charaters. 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.
      • You will need to re-write your constructors to allocate the correct amount of memory.
      • The default constructor should allocate 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.stringSize == 4.
      • Implement a destructor, copy constructor, constant time swap, and assignment operator for your ADT. Also re-implement += to deal with the dynamic aspects.
      • You will also have to update concat/operator+() to return the proper sized string result.
      • Implement a private method resetCapacity 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.
      • Additionally, implement two private constructors that will be useful for managing memory. String(int) creates a String of capacity n and length 0. String(int, const char[]) creates a string of capacity n with an initial value of the char[] (and length equal to the char[]). Both of these constructors break the class invariant and thus are private for use by the class only.

============================================================================

string.hpp:

#ifndef CS23001_STRING_INTERFACE_HPP
#define CS23001_STRING_INTERFACE_HPP

#include <iostream>

////////////////////////////////////////////////////
// CLASS INV: str[length()] == 0             &&
//            length()      == capacity()    &&
//            capacity()    == stringSize - 1
//
class String {
public:
            String        ();                               //Empty string
            String        (char);                           //String('x')
            String        (const char[]);                   //String("abc")
            String        (const String&);                  //Copy Constructor
            ~String       ();                               //Destructor
    void    swap          (String&);                        //Constant time swap
    String& operator=     (String);                         //Assignment Copy
    char&   operator[]    (int);                            //Accessor/Modifier
    char    operator[]    (int)                     const;  //Accessor
    int     capacity      ()                        const;  //Max chars that can be stored (not including null)
    int     length        ()                        const;  //Actual number of chars in string
    String  operator+     (const String&)           const;
    String& operator+=    (const String&);
    bool    operator==    (const String&)           const;
    bool    operator<     (const String&)           const;
    String  substr        (int, int)                const;  //The sub-string from staring position to ending position
    int     findch        (int,  char)              const;  //Find location of charater starting at a position
    int     findstr       (int,  const String&)     const;  //Find location of str starting at a position
    void    test_String   ();
    friend  std::ostream& operator<<(std::ostream&, const String&);
    friend  std::istream& operator>>(std::istream&, String&);


private:

  String (int n );                                               //String(10) - capacity 10, empty string

  String (int , const char []);                          //String(10, "abc") - capacity 10 with "abc"        

  void    resetCapacity (int);                            //Resets capacity to N, keeps string intact
   
    char    *str;                                           //Pointer to char[]
    int     stringSize;                                     //Size includes NULL terminator
};

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 "string.hpp"
#include <cassert>

String::String() {            // default constructor - empty string
  stringSize = 1;
  str = new char [stringSize];
  str[0] = 0;
}

String::String(char ch) {   
  stringSize = 2;
  str = new char [stringSize];
  str[0] = ch;
  str[1] = '\0';
}

//REQUIRES: str.length() < capacity()
//String a("abc")
//Takes character array and turns into string array
String::String(const char X[]) {
  int i = 0;
  while (X[i] != '\0') ++i;
  stringSize = i + 1;
  str = new char [stringSize];
  for(int j = 0; j < capacity(); ++j)
    str[j] = X[j];
  str[capacity()] = 0;
}

String::String(const String& rhs) {   //copy constructor
  stringSize = rhs.stringSize;
  str = new char [stringSize];
  for(int i = 0; i < capacity(); ++i)
    str[i] = rhs.str[i];
}

String::~String() {    //destructor
  delete[] str;
}

void String::swap (String& rhs) {    //Constant time swap
  char * temporary = str;
  str = rhs.str;
  rhs.str = temporary;
  int hold = stringSize;
  stringSize = rhs.stringSize;
  rhs.stringSize = hold;
}

String& String::operator= ( String rhs) {    // Assignment copy
  if (str == rhs.str) return *this;  //check to see if they are already pointing to the same address
  delete [] str;
  stringSize = rhs.stringSize;
  str = new char [stringSize];
  for (int i = 0; i < capacity(); ++i)
    str[i] = rhs.str[i];
  return *this;
}

//REQUIRES: 0 <= i < length()
// operator[] const --- allows access to const objects
char String::operator[](int i) const {
  assert( (i > 0) && (i < length()) );
  return str[i];
}

//REQUIRES: 0 <= i < length()
// operator[]       --- allows access / modification to non-const objects
char& String::operator[] (int i) {
  assert( (i >= 0) && (i < length() ) );
  return str[i];
}

int String::capacity() const {    //capacity = stringSize -1;
  return (stringSize - 1);
}

//ENSURES: Retval == i where str[i] = 0
int String::length() const {
  int result = 0;
  while (str[result] != '\0') 
    ++result;
  return result;
}

// retval == "xyzabc" where "xyx" + "abc"
String String::operator+(const String& rhs) const {
  String result;
  int offset = length();
  int i = 0;
  while(rhs.str[i] != 0) {
    result.str[offset + i] = rhs.str[i];
    ++i;
    if (offset + i == capacity()) break;
  }
    return result;
}

String operator+(char lhs, const String& rhs) {
  return String(lhs) + rhs;
}

String operator+(const char lhs[], const String& rhs) {
  return String(lhs) + rhs;
}

String& String::operator+=(const String& rhs) {
  *this = operator+(rhs);
  return *this;
}

bool String::operator==(const String& rhs) const {
  int i = 0;
  while ((str[i] != '\0') && (str[i] == rhs.str[i])) ++i;
  return str[i] == rhs.str[i];
}

bool operator==(char lhs, const String& rhs) {
  return String(lhs) == rhs;
}

bool operator==(char lhs[], const String& rhs) {
  return String(lhs) == rhs;
}

bool String::operator<(const String& rhs) const {
  int i = 0;
  while ((str[i] != 0) && (rhs.str[i] != 0) && (str[i] == rhs.str[i])) ++i;
  return str[i] < rhs.str[i];
}

bool operator<(char lhs, const String& rhs) {
  return String(lhs) < rhs;
}

bool operator<(const char lhs[], const String& rhs) {
  return String(lhs) < rhs;
}

bool operator!=(const String& lhs, const String& rhs) {
  return !(lhs == rhs) || (lhs == rhs);
}

bool operator<=(const String& lhs, const String& rhs) {
  return (lhs < rhs) || (lhs == rhs);
}

bool operator>(const String& lhs, const String& rhs) {
  return (rhs < lhs);
}

bool operator>=(const String& lhs, const String& rhs) {
  return !(lhs < rhs);
}

std::ostream& operator<<(std::ostream& out, const String& rhs) {
  out << rhs.str;
  return out;
}

std::istream& operator>>(std::istream& in, String& rhs) {
  char placehold[540000];
  in >> placehold;
  rhs = String(placehold);
  return in;
}


//REQUIRES: 0 <= start < length()
//ENSURES:  retval == i where str[i] == ch && i >= start
//          or retval == -1 if ch != s[start.length()-1]
int String::findch(int start, char ch) const {
  if ( (start < 0) || (start >= length()) ) return -1;
  int i = start;
  while (str[i] != 0) {
    if (str[i] == ch) return i;
    ++i;
  }
  return -1;
}


int String::findstr(int pos, const String& rhs) const {
  int i = pos;
  if ((pos < 0) || (pos >= length() - rhs.length()))
    return -1;
  if (length() < rhs.length())
    return -1;

  while ((str[pos] != 0) && (rhs.length() + pos - 1 <= length())) {
    if (rhs == substr(i, i + rhs.length() - 1))
      return pos;
    ++i;
  }
  return -1;
}

//REQUIRES: 0 <= start <= end < length()
//ENSURES:  retval == s[start, ..., end]
String String::substr(int start, int end) const {
  if (start < 0) return String();
  if (start > end) return String();
  if (end >= length()) return String();

  String result;
  int i = start;
  while (i <= end) {
    result += str[i];
    ++i;
  }
  return result;
}

String::String (int n) {                                               //String(10) - capacity 10, empty string
  stringSize = n;
  str = new char [stringSize];
  str[0] = 0;
}

String::String (int n, const char ch[]) {                          //String(10, "abc") - capacity 10 with "abc"
  stringSize  = n;
  str = new char [n];
  for (int i = 0; i < n; ++i)
    str[i] = ch[i];
}                                                        

void  String::resetCapacity (int n ) {                            //Resets capacity to N, keeps string intact
  int smaller = stringSize;
  if (smaller > n) smaller = n;
  stringSize = n;
  char * tmp = new char [stringSize];
  for (int i = 0; i < smaller; ++i)
    tmp[i] = str[i];
  delete [] str;
  str = tmp;
}


void String::test_String() {
  String testing(5);
  assert(testing.length() == 0);
  assert(testing.capacity() == 5);

  String test(15);
  assert(test.length() == 0);
  assert(test.capacity() == 15);

  String CharArray(10, "abc");
  assert(CharArray.length() == 3);
  assert(CharArray.capacity() == 10);
}

============================================================================

concat test .cpp:

#include "string.hpp"
#include <cassert>
#include <iostream>

int main ()
{
  {
    // TEST
    String  str = "x";
    String str2 = "y";
    String result;
    result = str+str2;
    std::cout<< str << " " << str2 << " " <<result<<std::endl;
    // VERIFY
    assert(result == "xy");
  }

  {
   // TEST
    String  str = "xyz";
    String str2 = "abc";
    String result;
    result = str+str2;
    // VERIFY
    assert(result == "xyzabc");
  }
  {
    // TEST
    String  str = "qlW3KSqbFk";
    String str2 = "f6iSmJhRTl";
    String result;
    result = str+str2;
    // VERIFY
    assert(result == "qlW3KSqbFkf6iSmJhRTl");
  }
  {
    //------------------------------------------------------
    // SETUP FIXTURE

    // TEST
    String  str = "lZ8kmGDuKeqzqPOmvthx94jQQg46C8";
    String str2 = "SgiwD";
    String result;
    result = str+str2;
    // VERIFY
    assert(result == "lZ8kmGDuKeqzqPOmvthx94jQQg46C8SgiwD");
  }
std::cout << "Done testing Concatination Constructor." << std::endl;
}

Solutions

Expert Solution

// ============================================================================

// string.cpp:

#include <iostream>

#include "string.hpp"

#include <cassert>

using namespace std;

String::String() { // default constructor - empty string

stringSize = 1;

str = new char [stringSize];

str[0] = 0;

}

String::String(char ch) {

stringSize = 2;

str = new char [stringSize];

str[0] = ch;

str[1] = '\0';

}

//REQUIRES: str.length() < capacity()

//String a("abc")

//Takes character array and turns into string array

String::String(const char X[]) {

int i = 0;

while (X[i] != '\0') ++i;

stringSize = i + 1;

str = new char [stringSize];

for(int j = 0; j < capacity(); ++j)

str[j] = X[j];

str[capacity()] = 0;

}

String::String(const String& rhs) { //copy constructor

stringSize = rhs.stringSize;

str = new char [stringSize];

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

str[i] = rhs.str[i];

}

String::~String() { //destructor

delete[] str;

}

void String::swap (String& rhs) { //Constant time swap

char * temporary = str;

str = rhs.str;

rhs.str = temporary;

int hold = stringSize;

stringSize = rhs.stringSize;

rhs.stringSize = hold;

}

String& String::operator= ( String rhs) { // Assignment copy

if (str == rhs.str) return *this; //check to see if they are already pointing to the same address

delete [] str;

stringSize = rhs.stringSize;

str = new char [stringSize];

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

str[i] = rhs.str[i];

return *this;

}

//REQUIRES: 0 <= i < length()

// operator[] const --- allows access to const objects

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

assert( (i > 0) && (i < length()) );

return str[i];

}

//REQUIRES: 0 <= i < length()

// operator[] --- allows access / modification to non-const objects

char& String::operator[] (int i) {

assert( (i >= 0) && (i < length() ) );

return str[i];

}

int String::capacity() const { //capacity = stringSize -1;

return (stringSize - 1);

}

//ENSURES: Retval == i where str[i] = 0

int String::length() const {

int result = 0;

while (str[result] != '\0')

++result;

return result;

}

// retval == "xyzabc" where "xyx" + "abc"

String String::operator+(const String& rhs) const {

char *c = new char[length() + rhs.stringSize];

int i = 0;

while(str[i] != 0) {

c[i] = str[i];

++i;

}

int j = 0;

while(rhs.str[j] != 0) {

c[i++] = rhs.str[j++];

}

c[i] = '\0';

String *k = new String(c);

return *k ;

}

String operator+(char lhs, const String& rhs) {

return String(lhs) + rhs;

}

String operator+(const char lhs[], const String& rhs) {

return String(lhs) + rhs;

}

String& String::operator+=(const String& rhs) {

*this = operator+(rhs);

return *this;

}

bool String::operator==(const String& rhs) const {

int i = 0;

while ((str[i] != '\0') && (str[i] == rhs.str[i])) ++i;

return str[i] == rhs.str[i];

}

bool operator==(char lhs, const String& rhs) {

return String(lhs) == rhs;

}

bool operator==(char lhs[], const String& rhs) {

return String(lhs) == rhs;

}

bool String::operator<(const String& rhs) const {

int i = 0;

while ((str[i] != 0) && (rhs.str[i] != 0) && (str[i] == rhs.str[i])) ++i;

return str[i] < rhs.str[i];

}

bool operator<(char lhs, const String& rhs) {

return String(lhs) < rhs;

}

bool operator<(const char lhs[], const String& rhs) {

return String(lhs) < rhs;

}

bool operator!=(const String& lhs, const String& rhs) {

return !(lhs == rhs) || (lhs == rhs);

}

bool operator<=(const String& lhs, const String& rhs) {

return (lhs < rhs) || (lhs == rhs);

}

bool operator>(const String& lhs, const String& rhs) {

return (rhs < lhs);

}

bool operator>=(const String& lhs, const String& rhs) {

return !(lhs < rhs);

}

std::ostream& operator<<(std::ostream& out, const String& rhs) {

out << rhs.str;

return out;

}

std::istream& operator>>(std::istream& in, String& rhs) {

char placehold[540000];

in >> placehold;

rhs = String(placehold);

return in;

}


//REQUIRES: 0 <= start < length()

//ENSURES: retval == i where str[i] == ch && i >= start

// or retval == -1 if ch != s[start.length()-1]

int String::findch(int start, char ch) const {

if ( (start < 0) || (start >= length()) ) return -1;

int i = start;

while (str[i] != 0) {

if (str[i] == ch) return i;

++i;

}

return -1;

}


int String::findstr(int pos, const String& rhs) const {

int i = pos;

if ((pos < 0) || (pos >= length() - rhs.length()))

return -1;

if (length() < rhs.length())

return -1;

while ((str[pos] != 0) && (rhs.length() + pos - 1 <= length())) {

if (rhs == substr(i, i + rhs.length() - 1))

return pos;

++i;

}

return -1;

}

//REQUIRES: 0 <= start <= end < length()

//ENSURES: retval == s[start, ..., end]

String String::substr(int start, int end) const {

if (start < 0) return String();

if (start > end) return String();

if (end >= length()) return String();

String result;

int i = start;

while (i <= end) {

result += str[i];

++i;

}

return result;

}

String::String (int n) { //String(10) - capacity 10, empty string

stringSize = n;

str = new char [stringSize];

str[0] = 0;

}

String::String (int n, const char ch[]) { //String(10, "abc") - capacity 10 with "abc"

stringSize = n;

str = new char [n];

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

str[i] = ch[i];

}

void String::resetCapacity (int n ) { //Resets capacity to N, keeps string intact

int smaller = stringSize;

if (smaller > n) smaller = n;

stringSize = n;

char * tmp = new char [stringSize];

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

tmp[i] = str[i];

delete [] str;

str = tmp;

}


void String::test_String() {

String testing(5);

assert(testing.length() == 0);

assert(testing.capacity() == 5);

String test(15);

assert(test.length() == 0);

assert(test.capacity() == 15);

String CharArray(10, "abc");

assert(CharArray.length() == 3);

assert(CharArray.capacity() == 10);

}

============================================================================
All the Test Passed,

SEE OUTPUT

Thanks, PLEASE COMMENT if there is any concern. PLEASE UPVOTE





Related Solutions

I cannot get this code to run on my python compiler. It gives me an expected...
I cannot get this code to run on my python compiler. It gives me an expected an indent block message. I do not know what is going on. #ask why this is now happenning. (Create employee description) class employee: def__init__(self, name, employee_id, department, title): self.name = name self.employee_id = employee_id self.department = department self.title = title def __str__(self): return '{} , id={}, is in {} and is a {}.'.format(self.name, self.employee_id, self.department, self.title)    def main(): # Create employee list emp1...
I get an error 1452 saying it cannot add or update my foreign key. is there...
I get an error 1452 saying it cannot add or update my foreign key. is there a way to fix this
I have three different homework questions I cannot seem to get My hw is due at...
I have three different homework questions I cannot seem to get My hw is due at 12 so if anyone can help that would be helpful Thank you 1)   For a car moving with speed v, the force of air drag is proportional to v2. If the power output of the car's engine is quadrupled, by what factor does the speed of the car increase? 2)Tarzan (m = 76 kg) commutes to work swinging from vine to vine. He leaves...
This is the HW question I cannot get the correct answer for. I've completed the first...
This is the HW question I cannot get the correct answer for. I've completed the first step but I cannot seem to get the correct numbers for EFN for 20, 25 and 30%!?!? See below for given financial statements and my table with the pro forma of 20, 25 and 30% numbers The most recent financial statements for Scott, Inc., appear below. Interest expense will remain constant; the tax rate and the dividend payout rate also will remain constant. Costs,...
Could you double check my program? I cannot get it to run. If you could tell...
Could you double check my program? I cannot get it to run. If you could tell me any changes that need to be made as well show the output I would greatly appreciate it. LinkedList.java public class LinkedList { class Node{ int value; Node nextElement; public Node(int value) { this.value = value; this.nextElement = null; } } public Node first = null; public Node last = null; public void addNewNode(int element) { Node newValueNode = new Node(element); if(first == null)...
Title to personal property cannot pass if it is a. abandoned b. stolen c. still in...
Title to personal property cannot pass if it is a. abandoned b. stolen c. still in the possession of the seller d. if there is no document of title in existence.
I have to code the assignment below. I cannot get the program to work and I...
I have to code the assignment below. I cannot get the program to work and I am not sure what i am missing to get the code to work past the input of the two numbers from the user. My code is listed under the assignment details. Please help! Write a Java program that displays the prime numbers between A and B. Inputs: Prompt the user for the values A and B, which should be integers with B greater than...
Cannot figure out why my c++ program keeps crashing, I am attempting to have the user...
Cannot figure out why my c++ program keeps crashing, I am attempting to have the user decide the size of a 2d array then fill said array. #include <iostream> using namespace std; typedef int* IntArrayPtr; int main(void) { int column, row, i, j; IntArrayPtr *arr_num = new IntArrayPtr[row]; cout << " " << endl << " This program creates a 2D array of dynamic memory, fills it with user entered numbers, " << endl << " Then prints the array...
in java: In my code at have my last two methods that I cannot exactly figure...
in java: In my code at have my last two methods that I cannot exactly figure out how to execute. I have too convert a Roman number to its decimal form for the case 3 switch. The two methods I cannot figure out are the public static int valueOf(int numeral) and public static int convertRomanNumber(int total, int length, String numeral). This is what my code looks like so far: public static void main(String[] args) { // TODO Auto-generated method stub...
Hi, I am running C# in Vis. Studio 2019 community. Trying to get my program to...
Hi, I am running C# in Vis. Studio 2019 community. Trying to get my program to populate the username in the program after entered. I can enter a name and the three scores and average them as the program needs but the name is not adding next to the "Students name: " in the program. Any help would be appreciated and please place a note for what I am doing wrong. Thank you using System; using System.Collections.Generic; using System.Linq; using...
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT