hi,
the following program has got to take a user inputted string and allows the user to see the postion of each character in the array i.e.
T H I S I S A T E S T
0 1 2 3 4 5 6 7 8 9 10 11 12

then it ask the user to search for any of the characters and it gives them their first and last position i.e for T 1st =0 last = 12

then it has to reverse the string. At first I had this working in one class, but I now need to split it into seperate cpp and header files.

but now i'm getting errors that i'm have problems fixing, probably something simiple that i just can't see.

Here are the 3 seperate files:

MyString.cpp

#include "MyString.h"

#include <string> 
#include <iostream>
#include <cstring>
#include <iomanip>
#include <string>

using std::cout; 
using std::cin; 
using std::endl; 
using std::setw;
/**
	MyString constructor, we set the str pointer to NULL to make sure it is initialised
	properly, then call the set() method to avoid code duplication.
 */
MyString::MyString(const char* inputString /* = NULL */) : str(NULL)
{
	set(inputString);
}

/** 
	Destructor, needs to deallocate all memory allocated to the object, in this case
	this means any memory that's allocated to store the string
*/
MyString::~MyString()
{
	// if the str pointer is not NULL, we need to deallocate the memory for the string
	// stored
	if (str != NULL)
	{
		delete[] str;
	}
}



void MyString::set(const char* inputString)
{
	 // Get amount mem that needs allocating from length of input string
	int inputLength = strlen(inputString);
	// Allocate memory for holding string, with 1 extra for null terminator
	str = new char[inputLength + 1];
	// Copy contents from input string to memory allocated
	strcpy (str , inputString);
}

void MyString::getLength(char Array[])
	
	{
		int i = 0; // declaring new int 'i' with a value of 0

		do // do this

		{
			i++; // increment 'i'
		}

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

		return i;
	}

void MyString::printFormatted(char Formatted[])
	{
		for (int format = 0; format < getLength(Formatted); ++format)
		{
			cout << setw(4) << Formatted[format];	
		}		
			cout << endl;

		for (int formatP = 0; formatP < getLength(Formatted); ++formatP)
		{
			cout << setw(4) << formatP;
		}

	cout << endl;
	} 

void MyString::findFirst(char First[], char c)
	{
		for (int findF = 0; findF < getLength(First); --findF)
		{
			if (First[findF] == c)
			{
				return findF;
			}
		}
		return -1;
	}

void MyString::findLast(char Last[], char c)
	{
		for (int findL = getLength(Last); findL > 0; --findL)
		{
			if (Last[findL] == c)
			{
				return findL;
			}
		}
		return -1;
	}


void MyString::reverse()
{
	for (int i = str1.length()-1; i>=0; i--)
	{
		cout <<str1 [i];
	}
}


ostream& operator<<(ostream& output, const MyString& mstr)
{
	// can access the private member string because the function is a 
	// friend of MyString.
	if (mstr.str != NULL)
	{
		output << mstr.str;
	}
	return output;
}

/** 
	Overloaded input stream operator

	A non-constant reference is used as the MyString object is being
	modified.
*/
istream& operator>>(istream& input, MyString& mstr)
{
	char strBuffer[MY_STRING_BUFFER_SIZE];
	input >> strBuffer;
	mstr.set(strBuffer);
	return input;
}

MyString.h

#ifndef MYSTRING_H
#define MYSTRING_H

#include <iostream>


// Allow MyString to use input/output streams by name
using std::ostream;
using std::istream;
using std::cout;
using std::endl;
// Used for character array buffers for reading
const int MY_STRING_BUFFER_SIZE = 256;

class MyString
{
private:
	char* str;

public:
		MyString(const char* inputString = NULL);

	/** 
		This is the destructor, and deallocates any memory that
		has been explicitly allocated to this class.
	*/
	~MyString();

		void set(const char* inputString);
	

	int getLength(/*char Array[]*/);
	
	
	void printFormatted(/*char Formatted[]*/);
	
	
	int findFirst(char c);
	
	
	int findLast(char c);
	
	
	void reverse();

	friend ostream& operator<<(ostream& output, const MyString& str);
	friend istream& operator>>(istream& input, MyString& str);
};


#endif	// MYSTRING_H

Main.cpp

#include <iostream>
#include "MyString.h"

using std::cin;
using std::cout;
using std::endl;

int main()
{
	// Create an empty MyString object
	MyString mstr;

	// Create a buffer so we can read input
	char strBuffer[MY_STRING_BUFFER_SIZE];
	
	// Read a line...
	cout << "Please input a string: ";
	cin.getline(strBuffer, MY_STRING_BUFFER_SIZE);

	// And put it into the MyString object
	mstr.set(strBuffer);

	// Print formatted...
	cout << "You input:" << endl;
	mstr.printFormatted();

	// Length
	cout << "Length of string: " << mstr.getLength() << endl;

	// Read character, and search
	char c;
	cout << "Please enter a character to search for: ";
	cin >> c;

	cout << "First occurrence of '" << c << "' at: " << mstr.findFirst(c) << endl;
	cout << "Last occurrence of '" << c << "' at: " << mstr.findLast(c) << endl;

	// Reverse
	mstr.reverse();
	cout << "Reverse string: " << mstr << endl;

	return 0;
}

Recommended Answers

All 9 Replies

So now you expect us to read the whole code line by line, or compile it ourselves to find the error that you could just post in 2 seconds?

sorry, there are a few errors just thought it would be easier to post the whole thing so you could copy it in and compile. But I will put the errors in now.

'void MyString::getLength(char [])' : overloaded member function not found in 'MyString'

and the same for the other 3 functions

there are two more errors which relate to declarations which I have now sorted, so dont worry about those

again sorry for the inconvience

Hi,

GetLength should not be void and should return an int
so rather

int MyString::getLength(char [])

This is unrelated to your compiler error, however, you've added #include <string> at the top of your program, but you're not using it; I imagine if you replaced every reference to char[] and char* with std::string instead, your program will get a lot easier.

<replied before reading... /ignore>

okay made some headway, got the program working up until the reverse function where I'm kinda stuck as to how to finish it off, think I have the general idea, and hopefully the right function algorithm.

in the header

void reverse();

here is the function within mystring.cpp that I'm having trouble with, deciding what to put in?

void MyString::reverse()
{
	for (int i = ()-1; i>=0; i--)
	{
		cout <<  [i];
	}
}

and the main cpp

int main()
{
	// Create an empty MyString object
	MyString mstr;

	// Create a buffer so we can read input
	char strBuffer[MY_STRING_BUFFER_SIZE];
	
	// Read a line...
	cout << "Please input a string: ";
	cin.getline(strBuffer, MY_STRING_BUFFER_SIZE);

	// And put it into the MyString object
	mstr.set(strBuffer);

	// Print formatted...
	cout << "You input:" << endl;
	mstr.printFormatted(strBuffer);

	 //Length
	cout << "Length of string: " << mstr.getLength(strBuffer) << endl;

	// Read character, and search
	char c;
	cout << "Please enter a character to search for: ";
	cin >> c;

	cout << "First occurrence of '" << c << "' at: " << mstr.findFirst(strBuffer, c) << endl;
	cout << "Last occurrence of '" << c << "' at: " << mstr.findLast(strBuffer, c) << endl;

	// Reverse
	cout << "Reverse string: " << mstr.reverse << endl;

	return 0;
}

I didnt read your code....I just read the question. From the question, It seems like the program is quite easy. I am not sure why you have so much code . If I am not Completely wrong, is this what you are trying to do?

#include <iostream>


using namespace std;

int main()
	  {
		string MyString;
		char SearchChar;
		char SearchType;
		string MyStringArray[20];
		int StringLength=0;
		veryBeginning:
		cout<<"input a string: ";
		cin>>MyString;
		StringLength = MyString.length();

		
		MyStringArray[StringLength];
		for(int i=0;i<StringLength;i++)
		   {
			cout<<MyString[i]<<" is at position "<<i<<endl;
		   }
		JustArraySearch:
		cout<<"Enter a search query: ";
		cin>>SearchChar;

		for(int j=0;j<StringLength;j++)
		  {
			if(MyString[j] == SearchChar)
			  {
				cout<<MyString[j]<<" is at position "<<j<<" and there are "<< j<<" items before it and "<<(StringLength-j)-1<<" items after it"<<endl;
			  }

		  }
		cout<<"Do you want to Search again Or Input a different string? Press 'y' for yes and 'n' for new string: ";
		cin>>SearchType;
		if(SearchType == 'y' || SearchType == 'Y')
		  {
			goto JustArraySearch;
		  }
		else	
		  {
			goto veryBeginning;		
		  }
		


		return 0;
		
	  }

output:
input a string: TESTING
T is at position 0
E is at position 1
S is at position 2
T is at position 3
I is at position 4
N is at position 5
G is at position 6
Enter a search query: I
I is at position 4 and there are 4 items before it and 2 items after it
Do you want to Search again Or Input a different string? Press 'y' for yes and 'n' for new string: Y
Enter a search query: E
E is at position 1 and there are 1 items before it and 5 items after it
Do you want to Search again Or Input a different string? Press 'y' for yes and 'n' for new string: N
input a string: HELLO
H is at position 0
E is at position 1
L is at position 2
L is at position 3
O is at position 4
Enter a search query: AND SO ON....

dont know. Let me know If I am completely off lol

From the question, It seems like the program is quite easy. I am not sure why you have so much code . If I am not Completely wrong, is this what you are trying to do?

If you'd read the OP's code, you'd see that they are trying to write a string class, not a procedure in main. Most programs can be written without using OO/classes, but that rather defeats the point if their goal is to write a class.

Also, having also read the question, and the rest of the thread, I think you're some way off the mark, since the OP wanted to find the first and last occurrances of a character rather than every single one (Something which std::string will do with find_first_of and find_last_of).

(Apologies to the OP for the off-topic tangent)

but as for your code, there are occasionally times and places where 'goto' is arguably acceptable to break out of complex blocks as a "Labelled break"; but goto loops are pure evil and epitomise ugly spaghetti code; If you're going to write code inside an infinite loop, then you should make it obvious to someone reading by writing while(true) or for(;;) or something similar instead of letting someone have to guess or trace through your goto labels;

The problem with code which masks its true intentions is this: if someone else maintaining your code reads something like that, they might not immediately see the infinite loop (especially not if they're on a tight deadline to do something); chances of them breaking something unintentionally is pretty high because your code is obfuscated.

A more readable version of that code without goto loops:

#include <iostream>
#include <string>
#include <cctype>

int main()
{
    while(true)
    {
        using namespace std;
        char input = 'N';
        string MyString;

        if('N' == toupper(input))
        {
            cout<<"input a string: ";
            cin >> MyString;

            for(int i(0); i!=MyString.length(); ++i)
                cout<<MyString.at(i)<<" is at position "<<i<<endl;
        }

        cout<<"Enter a search query: ";
        cin>>input;

        for(int i(0); i!=MyString.length(); ++i)
            if(MyString.at(i) == input)
                cout << input << " is at position "
                     << i     << " and there are "
                     << i     << " items before it and "
                     << (MyString.length()-1-i)
                     << " items after it" <<endl;

        cout<< "Do you want to Search again Or Input a different string?"
            << " Press 'y' for yes and 'n' for new string: ";
        cin >> input;
    }
}

haha..kk..I knew i got it wrong :p...but still gave it a try...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.