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

Lenguage C++ Task Create a class called MyString -- this will be a string class,

ID: 3912135 • Letter: L

Question

Lenguage

C++

Task

Create a class called MyString -- this will be a string class, which allows creation of string objects that have flexible sizes, intuitive operator syntax (through operator overloads), and other useful features. Your class will need to maintain the string internally as an array of characters, and since string sizes are not fixed, dynamic allocation techniques will need to be used in the class. Your class should maintain any string ojbect in a valid state at all times, and it should not allow any memory leaks.

The class should be written in the files mystring.h and mystring.cpp. I have provided a starter version of the file mystring.h, which already has many of the required features (i.e. the interface for users) declared. Do not change the prototypes of the already-declared functions.

Important Note: Since the intention of this assignment is for you to write a string class, you may NOT use the <string> class library in the creation of this assignment! Use of the standard C++ <string> library will result in an automatic 0 grade. The point here is to learn how to go about building such a library yourself.

Details and Requirements

Data

Your class must allow for storage of a flexibly-sized string of characters. Make sure to declare any appropriate member data variables in the header file. All member data of your class must be private.

Function descriptions

Standard Constructors

The default constructor should set the object to represent an empty string.

MyString(const char* ) -- this is a conversion constructor. A c-string will be passed as a parameter, and this constructor should set up the string object to store that string inside. This will enable type conversions from c-strings to MyString objects.

MyString(int ) -- this is a conversion constructor that should convert an integer value to a string representation. For example, if the value 1234 is passed in, the MyString object should now store the same string data that would be represented by the c-string "1234"

Note that these last two constructors will allow automatic type conversions to take place -- in this case, conversions from int to MyString and from c-style strings to type MyString -- when appropriate. This makes our operator overloads more versatile, as well. For example, the conversion constructor allows the following statements to work (assuming appropriate definitions of the assignment operator and + overloads described later):

Automatics
Since dynamic allocation is necessary, you will need to write appropriate definitions of the special functions (the "automatics"): destructor, copy constructor, assignment operator. The destructor should clean up any dynamic memory when a MyString object is deallocated. The copy constructor and assignment operator should both be defined to make a "deep copy" of the object (copying all dynamic data, in addition to regular member data), using appropriate techniques. Make sure that none of these functions will ever allow memory "leaks" in a program.

I/O functions

operator << -- insertion operator. This should print out the data from the MyString object, using the standard insertion operator syntax. There should be no extra formatting -- only the string stored in the object is printed (no newlines, extra spacing, etc).

operator >> -- extraction operator. This should read a string from an input stream. This operator should ignore any leading white space before the string data, then read until the next white space is encountered. Prior data in the MyString object is discarded. Note: Just like the operator>> for c-strings, this will only read one word at time.

getline function. This should read a string from an input stream. This operator should read everything from the input stream (first parameter) into the MyString object (second parameter) until the specified delimiter character is encountered. Notice that if the function is called with 3 parameters, the third parameter is the delimiter. If the function is called with 2 parameters, the delimiter is the newline ' ' by default. Prior data in the MyString object is discarded.


Comparison operators
Write overloads for all 6 of the comparison operators ( < , > , <= , >= , == , != ). Each of these operations should test two objects of type MyString and return an indication of true or false. You are testing the MyString objects for order and/or equality based on the usual meaning of order and equality for c-strings, which is lexicographic ordering. Remember that this is based on the order of the ascii characters themselves, so it's not exactly the same as pure "alphabetical" ordering.
Examples:

Concatenation operators

operator+ -- this should concatenate the two operands together and return a new MyString as a result.

operator+= -- this should concatenate the second operand onto the first one (i.e. changing the first one)

Examples:

Bracket operators
The bracket operator overloads have these prototypes:

Both of these should return the character at the given index position. Note that the first one returns the character by reference, so it allows the slot to be changed. The second returns by const reference and is a const member function and will run in read-only situations -- calls on const objects. Example calls:

Note that since the parameter in each is an unsigned int, it's not possible to have a negative array index passed in. If the index passed to the function is too big (out of bounds for what's currently stored), then:

The read-only/const version should just return the null character ''

The L-value version should resize the stored string to accomodate the specified index. All new slotsbetween the end of the prior string and the new index location should be set to spaces

Examples:

Standard accessors
getLength should return the length of the stored string (i.e. number of characters). For example, "Hello" has 5 characters
getCString should return the actual stored data as a c-string (i.e. null-terminated char array)

substring functions
There are two versions of substring -- a 1 parameter version and a 2-parameter version. Both should return a MyString object that consists of a portion (or "substring") of the original string. Neither should change the calling object. The first parameter represents the starting index of the substring. In the 2-parameter version, the second parameter gives the length of the substring to return (if the length is too long, default to the rest of the string ). In the 1-parameter version, the substring consists of the characters from the start index to the end of the string.
Examples:

insert() function
This function should change the calling object by inserting the data from the second parameter AT the index given by the first parameter. If the index is out of bounds (longer than the string's length), then just insert at the end. This function should also return the calling object.
Examples:

indexOf function
This function should search through the MyString to find the first occurence of the pattern or substring given in the parameter. The function should return the first index where it was found, or it should return -1 if the pattern is NOT found.
Examples:

General Requirements

As usual, no global variables. If you use any constants in the class, make them static

All member data should be private

Use appropriate good programming practices as denoted on previous assignments

Since the only output involved with your class will be in the << overload, your output must match mine exactly when running test programs.

You may NOT use classes from the STL (Standard Template Library) -- this includes class <string> -- as the whole point of this assignment is for you to learn how to manage dynamic memory issues inside of a class yourself, not rely on STL classes or the string class to do it for you.

You may use standard I/O libraries like iostream and iomanip, as well as the common C libraries cstring and cctype

Extra Credit:

Create an overloaded version of the - operator to "subtract" two MyString objects. The meaning of - is that it should return a MyString object that is the result of taking the first string and removing all instances of the second string from it.
Examples:

Hints and Tips:

Converting between ints and characters:
Be aware that 1 and '1' are not the same thing. '1' stores the ascii value of the character representing 1, which happens to be 49. The easiest way to convert between single digit integers and the character code representation is to add or subtract the ascii value of '0'.
Example:

Input:For the >> operator overload as well as the getline function, there are some issues to be careful about. You will not be able to just use the normal version of >> (or getline) for c-strings, because it attempts to read consecutive characters until white space or a delimiter is encountered. The problem here is that we will be entering an unknown number of characters, so you won't be able to allocate ALL of the space in advance. These operations may need to dynamically resize the array as you read characters in.

Sample main program

It will be up to you to write 1 or more test programs to test out the features of your class.

#include iostream» using namespace std; class Mystring friend ostream& operator (istream& , Mystring&); friend istrean& getline (istream& , MyString& , char delim = . "); friend Mystring operator+ (const Mystring&, const MyString&); friend bool operatork (const MyString&, const HyString&); friend bool operator (const Mystring&, const Mystring&); friend bool operator (const MyString&, const HyString&); friend bool operator (const MyString&, const HyString&); friend bool operator(const MyString&, const HyString&); friend bool operator !=(const MyString& , const MyString& ); public: Mystring) Mystring(const char* ); Mystring int); MyString); Mystring (const MyString&j; Mystring&operator-;(const MyString&); // assignment operator // empty string /I conversion from c-string conversion from int /I destructor /I copy constructor Mystring&operator;+ const Mystring& ); // concatenation/assignment // bracket operators to access char positions char& operatorl (unsigned int index); const char& operator[] (unsigned int index) const; // insert s into the string at position "index" Mystring& insert(unsigned int index, const MyString& s); // find index of the first occurrence of s inside the string // return the index, or -1 if not found int indexof (const MyString& s) const; int getLength const; const char getcstring) const; // return string length // return c-string equiv Mystring substring (unsigned int, unsigned int const; Mystring substring(unsigned int) const; private: / declare your member data here

Explanation / Answer

//Main.cpp
#include <iostream>
using namespace std;

#include "mystring.cpp"


int main()
{
    MyString s1;
    MyString s2("Hello, World");
    MyString s3 = "Welcome to Florida, have a nice day";
    MyString s4 = 12345;

    cout << "s1 = " << s1 << ' ';
    cout << "s2 = " << s2 << ' ';
    cout << "s3 = " << s3 << ' ';
    cout << "s4 = " << s4 << ' ';
    cout << ' ';

    cout << "Making the calls: "
         << " cin >> s1 "
         << " getline(cin, s2, ',') "
         << " getline(cin, s3) ";
    cout << "Enter some sentences: ";

    cin >> s1;
    getline(cin,s2,',');
    getline(cin,s3);

    cout << " New string values: ";

    cout << "s1 = " << s1 << ' ';
    cout << "s2 = " << s2 << ' ';
    cout << "s3 = " << s3 << ' ';
    cout << "--------------------------- ";

// ----------------------------------

    s1 = "Dog";
    s2 = "Food";
    MyString result = s1 + s2;
    cout << "result = " << result << ' ';

    s1 += s2;
    cout << "s1 = " << s1 << endl;

    const MyString s5 = "The concatenation of the catapult is a catamaran";
    cout << "s5 = " << s5 << endl;
    cout << "s5.indexOf("cat") returns " << s5.indexOf("cat") << ' ';
    cout << "s5.indexOf("dog") returns " << s5.indexOf("dog") << ' ';

    cout << "s5.getLength() = " << s5.getLength() << ' ';

    cout << "s5[4] = " << s5[4] << ' ';
    cout << "s5[10] = " << s5[10] << ' ';
    cout << "s5[15] = " << s5[15] << ' ';
    cout << "s5[52] = ascii " << static_cast<int>(s5[52]) << ' ';

    cout << "s5.substring(10,16) = " << s5.substring(10,16) << ' ';
    cout << "s5.substring(23) = " << s5.substring(23) << ' ';

    cout << "----------------------------- ";

    MyString words = "Greetings, Earthling";

    cout << "words = " << words << ' ';
    cout << "words.getLength() = " << words.getLength() << ' ';
    words[0] = 'K';
    words[4] = 'p';
    words[16] = 'z';

    cout << "words = " << words << ' ';

    words[25] = 'Q';
    cout << "words = " << words << ' ';

    words.insert(11, "Insane ");
    cout << "words = " << words << ' ';

    cout << "----------------------------- ";

    MyString x = "apple", y = "apply";
    cout << "x = " << x << ' ';
    cout << "y = " << y << ' ';

    if (x < y)       cout << "x < y is true ";
    if (x > y)       cout << "x > y is true ";
    if (x <= y)       cout << "x <= y is true ";
    if (x >= y)       cout << "x >= y is true ";
    if (x == y)       cout << "x == y is true ";
    if (x != y)       cout << "x != y is true ";

    cout << "-----------------------------------------" << endl;
    MyString s10 = "The bobcat concatenated the catapult with the catamaran";
    MyString t = "cat";
    MyString answer = s10 - t;

    cout << answer;

    return 0;
}
---------------------------------------------------------------------------------------
//MyString.cpp
#include "mystring.h"
#include <iostream>

using namespace std;

MyString::MyString()
{
    size = 1;
    string = new char[size];
    null = '';                         // stores the null character

    string[0] = '';                    // put nothing inside

}

MyString::MyString(const char* st)
{
    size = LenghOfChar(st);

    string = new char[size];                // creates a new dynamic array

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

        string[i] = st[i];                  // copy one array to the other one

    string[i] = '';                       // stores the null character at the end

    null = '';                            // stores the null character
}

MyString::MyString(int num)
{
    size = LenghtOfInt(num);

    string = new char[size];                        // creates the dynamic allocation for the conversion + 1 to null character

    int resto;
    char transfer;

    for (int i = size-1; i >= 0; i--)                  // while num != 0, keep reading the number
    {
        resto = num % 10;                           // takes the last digit
        num = num / 10;                             // remove the last digit
        transfer = resto + '0';                     // convert it to char
        string[i] = transfer;                       // store into the array
    }

    string[size] = '';

    null = '';                                    // stores the null character
}
MyString::~MyString()
{
    delete [] string;
}

MyString::MyString(const MyString& st)              // copy constructor, allow deep copy
{
    size = st.size;

    string = new char[st.size];                     // create a new array

    for(int i = 0; i < size; i++)
        string[i] = st.string[i];                   // copy one array to the other one.

    null = '';                                    // stores the null character
}

MyString& MyString::operator=(const MyString& st)
{
    if(this != &st)                          // only copy if the object passed is not already this one
    {
        delete [] string;                   // delete old data

        size = st.size;                 // null character
        string = new char[st.size];         // create a new array

        int i;

        for(i = 0; i < size; i++)
            string[i] = st.string[i];       // copy one array to the other one
    }

    return *this;                           // return the object itself, by reference
}

bool operator==(const MyString& st1 , const MyString& st2)
{
    int counter = 0;

    if(st1.size == st2.size)
    {
        for(int i = 0; i < st1.size; i++)
        {
            if(st1.string[i] == st2.string[i])
                counter++;
        }
    }
    else
        return false;               // different size couldn't be equal

    if(counter == st1.size)
        return true;                // same size and equal
    else
        return false;               // same size but not the same string
}

bool operator!=(const MyString& st1, const MyString& st2)
{
    if(st1 == st2)
        return false;
    else
        return true;
}

bool operator> (const MyString& st1, const MyString& st2)
{

    int i = 0;
    while ((st1.string[i] != '') && (st1.string[i] == st2.string[i]))         // while st1 is not null character and they are the same, keep searching
    {
        i++;
    }

    int resul = st1.string[i] - st2.string[i];                                  // return the subtraction of the two ascii letters

    if(resul > 0)                                   // negative number if st1 comes first
        return true;
    else
        return false;                                // positive number if st2 comes first
}

bool operator<=(const MyString& st1, const MyString& st2)
{
    if(st1 > st2)
        return false;
    else
        return true;
}

bool operator< (const MyString& st1, const MyString& st2)
{

    int i = 0;
    while ((st1.string[i] != '') && (st1.string[i] == st2.string[i]))         // while st1 is not null character and they are the same, keep searching
    {
        i++;
    }

    int resul = st1.string[i] - st2.string[i];                                  // return the subtraction of the two ascii letters

    if(resul >= 0)                                   // positive number if st2 comes first
        return false;
    else
        return true;                                // negative number if st1 comes first

}

bool operator>=(const MyString& st1, const MyString& st2)
{
    if(st1 < st2)
        return false;
    else
        return true;
}

ostream& operator<< (ostream& os, const MyString& my)
{

    for(int i = 0; my.string[i] != ''; i++)
        os << my.string[i];

    return os;
}

int MyString::CheckSpace(const char& ch)
{
    if(ch == ' ')
        return -1;                                      // -1 is space
    else if(ch == ' ')
        return -1;
    else if(ch == ' ')
        return -1;
    else if(ch == ' ')
        return -1;
    else if(ch == ' ')
        return -1;
    else if(ch == ' ')
        return -1;
    else
        return 0;                                       // not space
}

istream& operator>> (istream& is, MyString& my)
{
    my.Grow();                          // first grow

    int i = 0;
    char ch;
    int j = -1;                         // my flag

    while( j == -1)                     // ignore the white spaces
    {
        ch = is.get();
        j = my.CheckSpace(ch);
    }

    my.string[i] = ch;                  // catch the first non white space

    j = 0;                              // reset flag
    for(i = 1; j != -1; i++ )            // keeps reading until white space
    {
        if(i == my.size)                // out of space, grow
        {
            my.Grow();
        }

        ch = is.get();                  // catch the character
        j = my.CheckSpace(ch);          // verify if it is white space
        my.string[i] = ch;              // put it inside mystring

    }

    my.string[i] = '';                // overwrite the white space with the null character
}

istream& getline (istream& is, MyString& my, char delim)
{
    my.Grow();                          // first grow

    int i = 0;
    char ch;

    ch = is.get();
    my.string[i] = ch;

    for(i = 1; ch != delim; i++ )            // keeps reading until white space
    {
        if(i == my.size)                // out of space, grow
        {
            my.Grow();
        }

        ch = is.get();                  // catch the character

        if(ch == delim)
            my.string[i] = '';                // overwrite the white space with the null character
        else
            my.string[i] = ch;              // put it inside mystring
    }


}

MyString operator+ (const MyString& my1, const MyString& my2)
{
    MyString d1;

    d1.size = (my1.size + my2.size - 1);                                    // to delete the null value of the firts one

    d1.string = new char[d1.size];                         // dealocates a new array

    int i;
    for(i = 0; my1.string[i] != ''; i++)
        d1.string[i] = my1.string[i];                   // copy my1 to d1


    int k, j;
    for(j = i, k = 0; j < d1.size; k++, j++)
        d1.string[j] = my2.string[k];                   // copy my2 right after my1 finish

    d1.string[j] = my2.string[k];                       // copy '' to the end of the array

    return d1;
}

MyString& MyString::operator+=(const MyString& st)
{
    size = (size + st.size) - 1;                        // grow to store the two arrays and discard the null character of the firts array

    char* newString = new char[size];                   // creates a new array of the new size

    int i;
    for(i = 0; string[i] != ''; i++)                  // copies until null character
        newString[i] = string[i];                       // copy the first array into the new one


    int k;
    for(int j = i, k = 0; j < size; k++, j++)
        newString[j] = st.string[k];                   // copy st to the final of string


    delete [] string;                           // delete the old array
    string = newString;                         // points the old array to the new one

    return *this;                                   // return the calling object
}

const char* MyString::getCString() const
{
    return string;                           // Just return the calling object because my array is already a C-string array
}

char& MyString::operator[] (unsigned int index)
{
    if(index >= size)
    {
        while(index > size)                 // keep growing the array until index < size
        {
            Grow();
        }

        int i;
        for(i = 0; string[i] != ''; i++)
        {

        }

        int j = 0;
        for(j = i; j < index; j++)
            string[j] = ' ';                // set blank spaces between the end of the string and the index

        string[j] = string[index];
        string[j+1] = '';

        return string[index];

    }
    else
        return string[index];
}

const char& MyString::operator[] (unsigned int index) const
{

    if( index >= size)
        return null;                    // return the null character initialized in the constructors
    else
        return string[index];

}

MyString MyString::substring(unsigned int index) const
{
    MyString temp;                                  // create a temporaty MyString object

    temp.size = size - index;                       // update the size
    char* newString = new char[temp.size];

    int j;
    for(int i = index, j = 0; i < size; j++, i++)
        newString[j] = string[i];                 // copy the substring

    delete [] temp.string;
    temp.string = newString;

    return temp;                                    // return the substring
}

MyString MyString::substring(unsigned int index, unsigned int lenght) const
{
    MyString temp;                                      // create a temporaty MyString object

    int resul = size - index;

    if(resul < lenght)                                  // lenght too big
    {
        temp.size = size - index;                       // update the size

        int j;
        for(int i = index, j = 0; i < size; j++, i++)   // copy until the end of the string
            temp.string[j] = string[i];                 // copy the substring
    }
    else
    {
        temp.size = lenght;

        int j;
        for(int i = index, j = 0; j < temp.size; j++, i++)
            temp.string[j] = string[i];                 // copy the substring
    }


    return temp;                                        // return the substring
}

MyString& MyString::insert(unsigned int index, const MyString& s)
{
    if(index > size)
    {
        int newSize = (size + s.size) - 1;              // - 1 to discard null character

        int oldsize = size;

        while(size < newSize)                           // keep growing until size is enough
        {
            Grow();
        }

        int j;
        for(int i = oldsize, j = 0; j < s.size; j++, i++)
            string[i] = s.string[j];                    // copy string at the end of array

    }
    else
    {
        int newSize = (size + s.size) - 1;              // discard the null character of the first string

        char* newString = new char[newSize];

        int i;
        for(i = 0; i < index; i++)
            newString[i] = string[i];                   // copy the beginnig of the first string until index

        int j, k;
        for(j = i, k = 0; k < s.string[k] != ''; k++, j++)
            newString[j] = s.string[k];                 // copy the second string in the middle of the new one

        int m, l;
        for(l = j, m = index; string[m] != ''; l++, m++ )
            newString[l] = string[m];                   // copy the rest of the first string

        newString[l] = string[m];                       // copy the null character

        size = newSize;
        delete [] string;
        string = newString;
    }

    return *this;
}

int MyString::getLength() const
{
    int counter = 0;

    for(int i = 0; string[i] != ''; i++)
        counter++;

    return counter;
}

int MyString::indexOf(const MyString& st) const
{
    int check = st.getLength();                    // stores the lenght of the string

    int counter = 0;                              // if counter == check, there is a substring
    int j = 0;
    int firstIndex = -1;
    int flag = 0;

    for(int i = 0; string[i] != ''; i++)               // goes throught the string
    {
        if(flag == 1)
            break;

        for(j = counter; j < st.string[j] != ''; j++)     // goes throught the st.string
        {
            if(st.string[j] == string[i])                     // if the first letter of st.string is equal to the letter of string
            {
                counter++;                                  // counter increase

                if(counter == check)                        // if counter == check (the size of the substring), so the substring exist
                {
                    flag = 1;                               // to leave the first loop
                    firstIndex = (i - counter) + 1;         // return the index of the first match
                }
                break;                                      // leave the loop to move one unit forward into the string

            }
            else
            {
                j = 0;                                      // reset the second loop
                counter = 0;                                // reset the counter
                break;                                      // leave the loop to move one unit forward into the string
            }
        }
    }

    return firstIndex;                                      // return the index

}

void MyString::Grow()
{
    size = size + 5;

    char* newString = new char[size];                                // build a new array of size + 5

    int i;
    for(i = 0; string[i] != ''; i++)
        newString[i] = string[i];                                   // copy old array to the new one

    newString[i] = string[i];                                       // copy the null character

    delete [] string;                                               // delete old array
    string = newString;                                             // points the new array to the old one
}

int MyString::LenghtOfInt(int num)
{
    int counter = 0;

    if(num == 0)
        counter = 1;

    for(counter = 0; num != 0; counter++)
        num = num / 10;


    return counter;
}

int MyString::LenghOfChar(const char* st)
{
    int counter = 0;

    for(int i = 0; st[i] != ''; i++)
        counter++;

    return counter+1;                           // count the null character
}

// extra credit
MyString operator- (MyString my1, const MyString& my2)
{
    int index = my1.indexOf(my2);           // catch the first index

    if(index < 0)                           // check if there is a substring
        return my1;
    else
    {
        while (index > 0)                   // while there is a substring
        {
            int test = my1.getLength();
            int resul = test - index;
            int lenght = my2.getLength();

            if(resul == lenght)             // if substring is at the end
            {
                my1.string[index] = '';   // just add the null character

                index = my1.indexOf(my2);   // call for check new substring

            }
            else
            {
                int j, i;
                for(i = index, j = 0; i + lenght < test; j++, i++)
                    my1.string[i] = my1.string[i + lenght];             // delete the substring from the string

                my1.string[i] = '';                                   // put the null character at the end

                index = my1.indexOf(my2);                               // call for check new substring

            }
        }
    }

    return my1;                                                     // return the new string

}
-----------------------------------------------------------------------------------------------------------
#include <iostream>
using namespace std;

class MyString
{
    friend ostream& operator<< (ostream& os, const MyString& my);
    friend istream& operator>> (istream& is, MyString& my );
    friend istream& getline (istream& is, MyString& my, char delim = ' ');

    friend MyString operator+ (const MyString& my1, const MyString& my2);

    friend bool operator< (const MyString& st1, const MyString& st2);
    friend bool operator> (const MyString& st1, const MyString& st2);
    friend bool operator<=(const MyString& st1, const MyString& st2);
    friend bool operator>=(const MyString& st1, const MyString& st2);
    friend bool operator==(const MyString& st1 , const MyString& st2);
    friend bool operator!=(const MyString& st1, const MyString& st2);

public:
    MyString();               // empty string
    MyString(const char* st);       // conversion from c-string
    MyString(int num);           // conversion from int
    ~MyString();               // destructor
    MyString(const MyString& st);       // copy constructor
    MyString& operator=(const MyString& st);   // assignment operator

    MyString& operator+=(const MyString& st); // concatenation/assignment

    // bracket operators to access char positions
    char& operator[] (unsigned int index);
    const char& operator[] (unsigned int index) const;

    // insert s into the string at position "index"
    MyString& insert(unsigned int index, const MyString& s);

    // find index of the first occurrence of s inside the string
    // return the index, or -1 if not found
    int indexOf(const MyString& st) const;

    int getLength() const;       // return string length
    const char* getCString() const;   // return c-string equiv

    MyString substring(unsigned int index, unsigned int lenght) const;
    MyString substring(unsigned int index) const;

    // extra credit
    friend MyString operator- (MyString my1, const MyString& my2);

private:

    char* string;
    int size;
    int LenghtOfInt(int num);
    int LenghOfChar(const char* st);
    char null;
    void Grow();
    int CheckSpace(const char& ch);
};

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