Hello,

I am a beginning level C++ programmer. I have an assignment in which I need to create my own basic string class. There are several methods that I need to support, such as leftTrim, righttrim, toLowerCase, toUpperCase. I have been able to handle all of those, but I am now trying to code a substring class.

The prototype is defined as substring(int start, int end), the method should return a new string that is a substring of the string object that the mehod is being used against.

The example that I was able to get from my teacher is:

~~~~~~~~~~

//my class is called mystring

//initialize the variable temp
mystring temp (“hello”);

//return the value of substring to temp2, the value of the string would be “hel”
mystring temp2 = temp.substring(0,2);

~~~~~~~~~~~

The problem that I think I am having (I’m not completely sure) is trying to return an object of mystring from the substring method. My thought was that I would need to have an object of type mystring defined within the class mystring. See the class definition below) I would then modify that object to contain the substring and return that object.

First I tried declaring the variable as - mystring m_mystringTemp -, but the compiler complained:

error C2460: 'm_mystringTemp' : uses 'mystring', which is being defined
c:\cis569 _obj_or_prog_with_c++\assn3\mystring.h(19) : see declaration of 'mystring'

I then changed it to a pointer and did not receive this error. But I get a run time error when I execute the program. When I step thru the program, I see that is calling a constructor at the time that it is returning the value from the substring method and that is where the error occurs. But I am not sure why the constructor is being called or what to do next.

The code for the substring method is incomplete, I was just starting when I ran into this issue.

Below I will include the mystring,h file and the mystring.cpp file in case it is needed. I am not looking for someone to write the code, just help me understand what I am missing or doing wrong.

Thanks for any help,
Paul

################################################## ###



Mystring.h


#include <iostream>
using namespace std;

class mystring
{
public:
mystring();
mystring(char* charArray);
mystring(const mystring &string);
virtual ~mystring();

char charAt(int index);
bool concat(mystring string);
mystring substring(int start, int end);
void toLowerCase(void);
void toUpperCase(void);
void trim(void);
void rightTrim(void);
void leftTrim(void);

char *display(void);



private:
char *m_buff; //pointer to a character array
char *m_buffTemp;
int counter1;
int counter2;
mystring *m_mystringTemp;


};


mystring.cpp


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
//Default constructor - allocate a new string containing no characters
mystring::mystring()
{
cout << "Inside the mystring() Constructor\n";
m_buff = (char *) malloc( sizeof(0));
m_buff= NULL;


//******************
m_buffTemp = (char *) malloc( sizeof(0));
m_buffTemp = NULL;
//******************


cout << "Leavingthe mystring()\n\n";

}

///////////////////////////////////////////////////////////////////////
//Constructor Two - Convert the array of characters
mystring::mystring(char *charArray)
{
cout << "Inside the mystring(char *charArray) Constructor\n";

//allocate memory
//m_buff = (char *) malloc( sizeof(charArray) +1);
m_buff = (char *) malloc( strlen(charArray) +1);


//copy charArray into m_buff variable
strcpy(m_buff,charArray);

//add the NULL value on end
m_buff[strlen(m_buff)] = '\0';


//******************
m_buffTemp = (char *) malloc( sizeof(0));
m_buffTemp = NULL;
//******************

cout << "m_buff =" << m_buff << endl;
cout << "Leaving mystring(char *charArray) constructor\n\n";

}



///////////////////////////////////////////////////////////////////////
//Constructor Four - Allocate a new string that contains the same sequence of characters
// as the string argument
//Question -
mystring::mystring(const mystring &string)
{
cout << "Inside the mystring(mystring string) Constructor\n";

//allocate memory
m_buff = (char *) malloc( strlen(string.m_buff) +1);

//copy string char* data into this new string object
strcpy(m_buff, string.m_buff);


//******************
m_buffTemp = (char *) malloc( sizeof(0));
m_buffTemp = NULL;
//******************


cout << "Leaving mystring(const mystring &string) constructor\n\n";
}


////////////////////////////////////////////////////////////////////////
// Destructor - Destructor - Destructor

mystring::~mystring()
{

if (m_buff !=NULL)
delete[]m_buff;

}



////////////////////////////////////////////////////////////////////////
// charAt -- charAt -- charAt
// Returns the character at the specified index
// Return -1 if the index is beyond the length of string or the string is NULL
char mystring::charAt(int index)
{
//if the string is empty return to calling method
if( m_buff == NULL )
{
return(-1);
}

cout<< "In charAt ";
cout<< "Buff -" << m_buff << "-" <<endl;

if(index > strlen(m_buff) || index < 0)
return(-1);
else
return(m_buff[index]);
}


//////////////////////////////////////////////////////////////////////////
// trim -- trim - trim
// Removes white space from both ends of this string

void mystring::trim(void)
{
cout << "Inside trim\n";

//if the string is empty return to calling method
if( m_buff == NULL )
{
return;
}

counter1=0;
counter2=strlen(m_buff);

//allocate memory for temporary buffer
m_buffTemp = (char *) malloc( strlen(m_buff) +1);

//skip all blanks at beginning and get index value
while(m_buff[counter1]==' ')
{
counter1++;
}

cout << "Counter 1 = " << counter1 << endl;

//skip all blanks at end and get index value
while(m_buff[counter2--]==' ')
{
counter2--;
}
cout << "Counter 2 = "<< counter2 << endl;

//copy the trimmed text to a temporary string and add NULL
strncpy(m_buffTemp,&m_buff[counter1],counter2 - counter1);
m_buffTemp[counter2 - counter1] = '\0';
cout << "Trimmed text = -" << m_buffTemp << "-"<<endl;

//copy the temporary string back over original
strcpy(m_buff, m_buffTemp);
cout << "Original text now trimmed -" << m_buff << "-" <<endl;

}



//////////////////////////////////////////////////////////////////////////
// rightTrim -- rightTrim - rightTrim
// Removes white space from right end of this string

void mystring::rightTrim(void)
{

//if the string is empty return to calling method
if( m_buff == NULL )
{
return;
}

cout << "Inside rightTrim - Text -" << m_buff << "-" << "\n";

counter1=0;
counter2=strlen(m_buff);

//allocate memory for temporary buffer
m_buffTemp = (char *) malloc( strlen(m_buff) +1);

//skip all blanks at end and get index value
while(m_buff[counter2--]==' ')
{
counter2--;
}
cout << "Counter 2 = "<< counter2 << endl;

//copy the trimmed text to a temporary string and add NULL
strncpy(m_buffTemp,&m_buff[counter1],counter2 - counter1);
m_buffTemp[counter2 - counter1] = '\0';
cout << "RightTrimmed text = -"<< m_buffTemp << "-" << endl;

//copy the temporary string back over original
strcpy(m_buff, m_buffTemp);
cout << "Original text now RightTrimmed -" << m_buff << "-" <<endl;


}


//////////////////////////////////////////////////////////////////////////
// leftTrim -- leftTrim - leftTrim
// Removes white space from left end of this string

void mystring::leftTrim(void)
{

//if the string is empty return to calling method
if( m_buff == NULL )
{
return;
}

cout << "Inside leftTrim - Text -" << m_buff << "-" << "\n";

counter1=0;
counter2=strlen(m_buff);

//allocate memory for temporary buffer
m_buffTemp = (char *) malloc( strlen(m_buff) +1);

//skip all blanks at beginning and get index value
while(m_buff[counter1]==' ')
{
counter1++;
}

cout << "Counter 1 = " << counter1 << endl;

//copy the trimmed text to a temporary string and add NULL
strncpy(m_buffTemp,&m_buff[counter1],counter2 - counter1);
m_buffTemp[counter2 - counter1] = '\0';
cout << "LeftTrimmed text = -" << m_buffTemp << "-"<<endl;

//copy the temporary string back over original
strcpy(m_buff, m_buffTemp);
cout << "Original text now LeftTrimmed -" << m_buff << "-" <<endl;

}



//////////////////////////////////////////////////////////////////////////
// toLowerCase -- toLowerCase -- toLowerCase
// Converts this string to lowercase

void mystring::toLowerCase(void)
{
cout << "Inside toLowerCase\n";

//if the string is empty return to calling method
if( m_buff == NULL )
{
return;
}

counter1=strlen(m_buff);
counter2 = 0;

//convert all to lowercase
while(m_buff[counter2]!='\0' || counter2 < counter1)
{

m_buff[counter2]=tolower(m_buff[counter2]);
counter2++;
}

cout << "Original text now tolower -" << m_buff << "-" <<endl;

}


//////////////////////////////////////////////////////////////////////////
// toUpperCase -- toUpperCase -- toUpperCase
// Converts this string to uppercase

void mystring::toUpperCase(void)
{
cout << "Inside toUpperCase\n";

//if the string is empty return to calling method
if( m_buff == NULL )
{
return;
}

counter1=strlen(m_buff);
counter2 = 0;

//convert all to uppercase
while(m_buff[counter2]!='\0' || counter2 < counter1)
{

m_buff[counter2]=toupper(m_buff[counter2]);
counter2++;
}

cout << "Original text now toupper -" << m_buff << "-" <<endl;

}

//////////////////////////////////////////////////////////////////////////
// concat -- concat - concat
// Concatenates the specified string to the end of this string
// NULL - if the object string m_buff is NULL, it will have memory allocated
// for the size of the concated string and then that concated string
// string.m_buff will be copied over. The first check is if both
// strings are NULL, if so then return a 0 value.
// Return a value of 1 if successfull
// QUESTION - Code for an empty string - test it out
bool mystring::concat(mystring string)
{
cout << "Inside concat\n";

//Test if string to concat is NULL
if(string.m_buff == NULL)
return(0);

//Test if the m_buff string is NULL, if so allocate mem and copy over the
// string to concat and return a true value
if(m_buff == NULL)
{
m_buff = (char *) malloc( strlen(string.m_buff) +1);
strcpy(m_buff, string.m_buff);
return(1);
}


//**Logic below will get used if neither string is NULL


//allocate memory for temporary buffer that is enough for both strings
m_buffTemp = (char *) malloc( strlen(m_buff) + strlen(string.m_buff) +1);


//copy over this objects string and then concat the other string into temp
strcpy(m_buffTemp, m_buff);
strcat(m_buffTemp, string.m_buff);
cout << "The concat string in buffTemp -" <<m_buffTemp <<"-\n";

//delete the m_buff, re-allocate mem and copy the temporary back over it
free(m_buff);
m_buff = (char *) malloc( strlen(m_buffTemp) +1);
strcpy(m_buff, m_buffTemp);
cout << "The concat string in m_buff in concat -" <<m_buffTemp <<"-\n";

//delete the m_buffTemp and set to NULL, not sure if need to set to NULL
// need to see if free does this for you.
free(m_buffTemp);
m_buffTemp = NULL;

return(1);

}



//////////////////////////////////////////////////////////////////////////
// subString -- subString -- subString
// Returns a new string that is a substring of thsi string (start at
// int1 and end at int2
// QUESTION - Code for an empty string - test it out
mystring mystring::substring(int start, int end)
{

//check that the start value is valid, if not then leave method
if(start < 0 || start > strlen(m_buff))
return(*m_mystringTemp);


return(*m_mystringTemp);

//check that end value is valid, if not then reassign a value that
// is equal to the length of the string that this method is acting on
// This will allow the method to continue without error


//copy the substring value into the temporary string class and then return it




}

//////////////////////////////////////////////////////////////////////////
// display
// Displays the m_buff data
char *mystring::display(void)
{
if(m_buff == NULL)
return (NULL);
else
return(m_buff);
}