hi, I've been staring at my program code forever now and I'm going in circle. I don't know what I've done wrong. Can anyone please help?
I'm supposed to design a month class that the following private members:
1) name: a MyString object that hold name of a month such as "January"
2) monthNumber: a int value that holds the number of month. January would be 1; Feb would be 2.

I have to have the following member functions:
1) a default constructor hat sets monthNumber to 1 and name to "January"
2) a constructor that accepts name of month as an argument. it should set name to the value passed as the argument and set monthNumber to the correct value
3) a constructor that accepts the number of month as an argument. it should set monthNumber to the value as the argument and set name to the correct month name
4) appropriate set and get functions for name and monthNumber
5) prefix and postfix overloaded ++ operator taht increment monthNumber and set name to the name of next month. EX: if monthNumber is set to 12, they should set monthNumber to 1 and name to "January"
6) prefix and postfix overloaded -- operator functions that decrement monthNumber and set name to the previous month. EX: if monthNumber is set to 1, they should set monthNumber to 12 and name to "December"

This is my code:

// Specification file for the MyString class
#ifndef MYSTRING_H
#define MYSTRING_H
#include <iostream>

using namespace std;

class MyString;	// Forward declaration.
ostream &operator<<(ostream &, MyString &);
istream &operator>>(istream &, MyString &);

// MyString class. An abstract data type for handling strings.

class MyString
{
private:
	char *str;
	int len;
public:
	MyString()					// Default constructor
		{ str = NULL; len = 0; }

	MyString(MyString &right)	// Copy constructor
		{ str = new char[right.length() + 1];
		  strcpy(str, right.getValue());
		  len = right.length(); }

	MyString(char *sptr)		// Constructor - initializes with
		{ len = strlen(sptr);	// a C-string.
		  str = new char[len + 1];
		  strcpy(str, sptr); }
    
	~MyString()					// Destructor
		{ if (len != 0) delete [] str; }
	
	int length()				// Returns the string length.
		{ return len; }
	
	char *getValue()			// Returns the string.
		{ return str; };
	
	// Overloaded operators
	MyString operator+=(MyString &);
	char *operator+=(const char *);
	MyString operator=(MyString &);
	char *operator=(const char *);
	int operator==(MyString &);
	int operator==(const char *);
	int operator!=(MyString &);
	int operator!=(const char *);
	bool operator>(MyString &);
	bool operator>(const char *);
	bool operator<(MyString &);
	bool operator<(const char *); 
	bool operator>=(MyString &);
	bool operator>=(const char*);
	bool operator<=(MyString &);
	bool operator<=(const char *);
	friend ostream &operator<<(ostream &, MyString &);
	friend istream &operator>>(istream &, MyString &);
};

#endif
//Month class

#ifndef MONTH_H
#define MONTH_H
#include "MyString.h"
#include <iostream>
using namespace std;

class Month 
{ 
private: 
    MyString name; 
    int monthNumber; 
public: 
    Month() 
    { monthNumber = 1; 
    name = "January"; 
    } 

    Month(char *month_pointer) 
    { 
        name = month_pointer; 
        if (month_pointer == "January") 
            monthNumber = 1; 
        else if(month_pointer == "February") 
            monthNumber = 2; 
        else if(month_pointer == "March") 
            monthNumber = 3; 
        else if(month_pointer == "April") 
            monthNumber = 4; 
        else if(month_pointer == "May") 
            monthNumber = 5; 
        else if(month_pointer == "June") 
            monthNumber = 6; 
        else if(month_pointer == "July") 
            monthNumber = 7; 
        else if(month_pointer == "August") 
            monthNumber = 8; 
        else if(month_pointer == "September") 
            monthNumber = 9; 
        else if(month_pointer == "October") 
            monthNumber = 10; 
        else if(month_pointer == "November") 
            monthNumber = 11; 
        else if(month_pointer == "December") 
            monthNumber = 12; 
    } 

    Month(int x) 
    { 
        monthNumber = x; 
		switch (monthNumber)
		{
        case 1: 
            name = "January"; 
			break;
        case 2: 
            name = "February";
			break;
        case 3: 
            name = "March"; 
			break;
        case 4: 
            name = "April"; 
			break;
        case 5: 
            name = "May"; 
			break;
        case 6:  
            name = "June"; 
			break;
        case 7: 
            name = "July"; 
			break;
        case 8: 
            name = "August"; 
			break;
        case 9: 
            name = "September"; 
			break;
        case 10: 
            name = "October"; 
			break;
        case 11: 
            name = "November"; 
			break;
        case 12: 
            name = "December"; 
			break;
    } 

    void setmonthName(char *month_pointer) 
    { name = month_pointer;} 

    void setmonthNumber(int x) 
    { monthNumber = x;} 

    MyString getmonthName() 
    { return name;} 

    int getmonthNumber() 
    { return monthNumber;} 

    Month operator++() 
    { 
        ++monthNumber; 
        if(monthNumber == 13) 
            monthNumber = 1; 
        //Month(); 
        return *this; 
    } 

    Month operator++(int) 
    { 
        Month temp(monthNumber); 
        monthNumber++; 
        if(monthNumber == 13) 
            monthNumber = 1; 
        Month(monthNumber); 
        return temp; 
    } 

    Month operator--() 
    { 
        --monthNumber; 
        if(monthNumber == 0) 
            monthNumber = 12; 
        Month(); 
            return *this; 
    } 

    Month operator--(int) 
    { 
        Month temp(monthNumber); 
        monthNumber--; 
        if(monthNumber == 0) 
            monthNumber = 12; 
        Month(); 
            return temp; 
    } 

}; 

ostream &operator << (ostream &strm, MyString &obj) 
{ 
    strm << obj.getmonthNumber << " is the number of the month." << endl; 
    strm << obj.getmonthName << " is the name of the month." << endl; 
    return strm; 
} 

istream &operator >> (istream &strm, MyString &obj) 
{ 
    int x; 
    cout << "Enter the month number: "; 
    strm >> x; 
    obj.setmonthNumber(x); 
    return strm; 
} 

#endif
//main program.cpp


// Chapter 14
// Programming Challenge 4: Month Class
#include <iostream>
#include "Month.h"
#include "MyString.h"
using namespace std;

int main()
{

	// Create a Month object
	Month m("October");

	cout << m.getmonthName() << endl;
	cout << m.getmonthNumber() << endl << endl;

	m.setName("July");
	cout << m.getmonthName() << endl;
	cout << m.getmonthNumber() << endl << endl;

	m.setNumber(2);
	cout << m.getmonthName() << endl;
	cout << m.getmonthNumber() << endl << endl;;

	// Test the prefix ++ operator.
	cout << ++m << endl;

	// Test the postfix ++ operator.
	cout << m++ << endl;
	cout << m << endl << endl;

	// Test the prefix -- operator.
	cout << --m << endl;

	// Test the postfix ++ operator.
	cout << m-- << endl;
	cout << m << endl << endl;

	return 0;
}

I'm pretty sure that the problem lies within the Month class. And I'm sure that MyString.h MyString.cpp, and the main program.cpp are fine.

you didn't say what the problem is. But I see a few problems in the Month class. Whenever the month number changes the month name must also change, and whenever the month name changes the month number must also change. I suggest moving those two large switch statements in the two class constructors into the setmonthName() and setmonthNumber() functions, then call these functions from the constructors and each of the overloaded operators. This will keep the month number and month name class objects synchronized.

An alternate solution would be to not keep the month name anyplace in the class. Only set the month number. When the name is needed, it can easily be obtained from the month number. That way no synchronization is necessary. Change the function setMonthName() to set the month number based on the string passed into the function. There is no reason to keep a copy of that string. And change getMonthName() to return the month name string that is appropriate for the month number. An array of month names makes all that very simple and short -- no switch statement is needed. For example:

std::string months[] = { "January","February" ...}
// assume n >= 1 and n <= 12
string getMonthName(int n) {return months[n-1];}


An alternate solution would be to not keep the month name anyplace in the class. Only set the month number. When the name is needed, it can easily be obtained from the month number. That way no synchronization is necessary. Change the function setMonthName() to set the month number based on the string passed into the function. There is no reason to keep a copy of that string. And change getMonthName() to return the month name string that is appropriate for the month number. An array of month names makes all that very simple and short -- no switch statement is needed. For example:

std::string months[] = { "January","February" ...}
// assume n >= 1 and n <= 12
string getMonthName(int n) {return months[n-1];}

Hi,
If I do it this way, then there is no need for the MyString class, right? I'm supposed to make name an MyString object.

you didn't say what the problem is.

This is the errors my compiler (MV C++ 6.0) gives me:
--------------------Configuration: Chapter 14 testing - Win32 Debug--------------------
Compiling...
testing.cpp
x:\dtran5.pds\chapter 14 testing\month.h(143) : error C2804: binary 'operator <<' has too many parameters
x:\dtran5.pds\chapter 14 testing\month.h(143) : error C2333: '<<' : error in function declaration; skipping function body
x:\dtran5.pds\chapter 14 testing\month.h(150) : error C2804: binary 'operator >>' has too many parameters
x:\dtran5.pds\chapter 14 testing\month.h(150) : error C2333: '>>' : error in function declaration; skipping function body
x:\dtran5.pds\chapter 14 testing\testing.cpp(5) : error C2059: syntax error : 'PCH creation point'
x:\dtran5.pds\chapter 14 testing\testing.cpp(6) : error C2238: unexpected token(s) preceding ';'
x:\dtran5.pds\chapter 14 testing\testing.cpp(8) : error C2059: syntax error : 'PCH creation point'
x:\dtran5.pds\chapter 14 testing\testing.cpp(9) : error C2334: unexpected token(s) preceding '{'; skipping apparent function body
x:\dtran5.pds\chapter 14 testing\testing.cpp(43) : fatal error C1004: unexpected end of file found
Error executing cl.exe.

testing.obj - 9 error(s), 0 warning(s)

Hi,
If I do it this way, then there is no need for the MyString class, right? I'm supposed to make name an MyString object.

Then nix my suggestion.

This is the errors my compiler (MV C++ 6.0) gives me:

month class is missing a close bracket } in the constructor that takes an integer. That is causing all the other errors.

This article has been dead for over six months. Start a new discussion instead.