开发者

Tuesday + 3 = Friday? C++ Programming Problem

Looking at the main function, we can see that I've Hard Coded the "Monday" into my setDay public function. It is easy to grab a day of the week from the user using a c-string (as I did in setDay), but how would I ask the user to add n to the day that is set, "Monday" and come up with "Thursday"? It is hard because typdef enum { INVALID, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY} doesn't interpret 9 is 0 and/or 10 as 1.

#include <iostre开发者_如何学Goam>

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

class DayOfTheWeek //class is encapsulation of functions and members that manipulate the data.
{
public:

 DayOfTheWeek(); // Constructor
 virtual ~DayOfTheWeek(); // Destructor

 void setDay(const char * day); // Function to set the day
 void printDay() const;      // Function to Print the day.
 const char * getDay() const;   // Function to get the day.

 const char * plusOneDay();  // Next day function
 const char * minusOneDay(); // Previous day function
 const char * addDays(int addValue);  // function that adds days based on parameter value

private:
 char * day; // variable for the days of the week.

};

DayOfTheWeek::DayOfTheWeek() : day(0)
{
// Usually I would allocate pointer member variables
// Here in the construction of the Object
}

const char * DayOfTheWeek::getDay() const
{
 return day; // we can get the day simply by returning it.
}

const char * DayOfTheWeek::minusOneDay()
{
 if ( strcmp( day, "Monday" ) == 0)
 {
  cout << "The day before " << day << " is ";
  return "Sunday";
 }
 else if ( strcmp( day, "Tuesday" ) == 0 )
 {
  cout << "The day before " << day << " is ";
  return "Monday";
 }
 else if ( strcmp( day, "Wednesday" ) == 0 )
 {
  cout << "The day before " << day << " is ";
  return "Tuesday";
 }
 else if ( strcmp( day, "Thursday" ) == 0 )
 {
  cout << "The day before " << day << " is ";
  return "Wednesday";
 }
 else if ( strcmp( day, "Friday" ) == 0 )
 {
  cout << "The day before " << day << " is ";
  return "Thursday";
 }
 else if ( strcmp( day, "Saturday" ) == 0 )
 {
  cout << "The day before " << day << " is ";
  return "Friday";
 }
 else if ( strcmp( day, "Sunday" ) == 0 )
 {
  cout << "The day before " << day << " is ";
  return "Saturday";
 }
 else
 {
  cout << "'" << day << "'";
  return "is an invalid day of the week!";
 } 
}

const char * DayOfTheWeek::plusOneDay()
{
 if ( strcmp( day, "Monday" ) == 0)
 {
  cout << "The day after " << day << " is ";
  return "Tuesday";
 }
 else if ( strcmp( day, "Tuesday" ) == 0 )
 {
  cout << "The day after " << day << " is ";
  return "Wednesday";
 }
 else if ( strcmp( day, "Wednesday" ) == 0 )
 {
  cout << "The day after " << day << " is ";
  return "Thursday";
 }
 else if ( strcmp( day, "Thursday" ) == 0 )
 {
  cout << "The day after " << day << " is ";
  return "Friday";
 }
 else if ( strcmp( day, "Friday" ) == 0 )
 {
  cout << "The day after " << day << " is ";
  return "Saturday";
 }
 else if ( strcmp( day, "Saturday" ) == 0 )
 {
  cout << "The day after " << day << " is ";
  return "Sunday";
 }
 else if ( strcmp( day, "Sunday" ) == 0 )
 {
  cout << "The day after " << day << " is ";
  return "Monday";
 }
 else
 {
  cout << "'" << day << "'";
  return " is an invalid day of the week!";
 }
}

const char * DayOfTheWeek::addDays(int addValue)
{
 if ( addValue < 0 )
 {
  if ( strcmp( day, "Monday" ) == 0)
  {
   cout << day << " - " << -addValue << " = ";
   return "Friday";
  }
  else if ( strcmp( day, "Tuesday" ) == 0 )
  { 
   cout << day << " - " << -addValue << " = ";
   return "Saturday";
  }
  else if ( strcmp( day, "Wednesday" ) == 0 )
  {
   cout << day << " - " << -addValue << " = ";
   return "Sunday";
  }
  else if ( strcmp( day, "Thursday" ) == 0 )
  {
   cout << day << " - " << -addValue << " = ";
   return "Monday";
  }
  else if ( strcmp( day, "Friday" ) == 0 )
  {
   cout << day << " - " << -addValue << " = ";
    return "Tuesday";
  }
  else if ( strcmp( day, "Saturday" ) == 0 )
  {
   cout << day << " - " << -addValue << " = ";
   return "Wednesday";
  }
  else if ( strcmp( day, "Sunday" ) == 0 )
  {
   cout << day << " - " << -addValue << " = ";
   return "Thursday";
  }
   else
  {
   cout << "'" << day << "' ";
   return "is an invalid day of the week! ";
  }
 }
 else // if our parameter is greater than 0 (positive)
 {
  if ( strcmp( day, "Monday" ) == 0)
  {
   cout << day << " + " << addValue << " = ";
   return "Thursday";
  }
  else if ( strcmp( day, "Tuesday" ) == 0 )
  {
   cout << day << " + " << addValue << " = ";
   return "Friday";
  }
  else if ( strcmp( day, "Wednesday" ) == 0 )
  { 
   cout << day << " + " << addValue << " = ";
   return "Saturday";
  }
   else if ( strcmp( day, "Thursday" ) == 0 )
  {
   cout << day << " + " << addValue << " = ";
   return "Sunday";
  }
  else if ( strcmp( day, "Friday" ) == 0 )
  {
   cout << day << " + " << addValue << " = ";
    return "Monday";
  }
  else if ( strcmp( day, "Saturday" ) == 0 )
  {
   cout << day << " + " << addValue << " = ";
   return "Tuesday";
  }
  else if ( strcmp( day, "Sunday" ) == 0 )
  {
   cout << day << " + " << addValue << " = ";
   return "Wednesday";
  }
  else
  {
   cout << "'" << day << "' ";
   return "is an invalid day of the week! ";
  }
 }
}

void DayOfTheWeek::printDay() const
{
 cout << "The Value of the " << day;
}

void DayOfTheWeek::setDay(const char * day)
{
 if (day)
 {// Here I am allocating the object member char day pointer
  this->day = new char[strlen(day)+1];
  size_t length = strlen(day)+1; // +1 for trailing null char
  strcpy_s(this->day , length , day); // copying c-strings
 }
 else day = NULL; // If their was a problem with the parameter 'day'
}

DayOfTheWeek::~DayOfTheWeek()  
{
 delete day; // Free the memory allocated in SetDay
}

int main()
{ 
 DayOfTheWeek MondayObject; // declare an object

 MondayObject.setDay("Monday"); // Call our public function 'setDay' to set a day of the week
 MondayObject.printDay();        // Call our public function 'printDay' to print the day we set

 cout << " object is " << MondayObject.getDay() << endl; // Print the value of the object

 cout << MondayObject.plusOneDay()  << endl;
 cout << MondayObject.minusOneDay() << endl;
 cout << MondayObject.addDays(3)    << endl;

   MondayObject.printDay();
 cout << " object is still " << MondayObject.getDay() << endl; // Print the value of the object

 cout << MondayObject.addDays(-3)  << endl;

 return 0;
}


Rather than trying to use strings to store what day it is, you probably just want to use an integer inside the class to store the day of the week. Integers and modulus arithmetic are most commonly used to store this sort of data.

If you store the days of the week as, say, Sunday to Monday are 0 through 6, you can use the modulus operator % to do easy operations on it; anytime you don't know if an operation is within that range, you can do

nDay = nDay % 7;

and it will arrive at the value you're expecting; if it has gone up from 6 to 9, for instance, it will wrap around back to 2.


You can use enums and encapsulate the Sunday-Monday rollover:

enum Weekday {
  INVALID,
  MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
};
Weekday operator+(Weekday w, int n) {
  if (w == INVALID) return w;
  n %= 7;
  if (n < 0) n += 7;
  return Weekday((n + (w - 1)) % 7 + 1);
}
Weekday operator+(int n, Weekday w) { return w + n; }
Weekday operator-(Weekday w, int n) { return w + -n; }
Weekday operator-(int n, Weekday w); // not defined -- doesn't make sense and not
// to be used

std::string str(Weekday d) {
  assert(INVALID <= d && d <= SUNDAY); // function precondition
  static char const* const days[] = {
    "INVALID",
    "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"
  };
  return days[d];
}

// you would probably not call this directly, but it shows how you simply have to
// pick what day int(0) means, and add any int to that day to get a Weekday
Weekday Weekday_from_num(int n, Weekday zero=MONDAY) {
  return zero + n;
}

Test:

int main() {
  assert(MONDAY + 1 == TUESDAY);
  assert(MONDAY + 8 == TUESDAY);
  assert(MONDAY - 1 == SUNDAY);
  assert(MONDAY - 8 == SUNDAY);

  cout << "MONDAY + 3 is " << str(MONDAY + 3) << '\n';
  return 0;
}

However, I'd drop the INVALID (which also simplifies the math). You've already written a Weekday_from_str function, you just have to adapt it to return this enum.


This kind of (frequently met) problem does not require writing a class, a namespace containing an enum and two functions is enough:

#include <iostream>
namespace day {

enum e_DAY { Sun, Mon, Tue, Wed, Thu, Fri, Sat };

inline e_DAY GetDay(unsigned int i)
{
    return (e_DAY)(i % 7);
}

inline const wchar_t* GetName(unsigned int i)
{
    static wchar_t* Names[] = { L"Sunday", L"Monday", L"Tuesday", L"Wednesday", L"Thursday", L"Friday", L"Saturday" };
    return Names[GetDay(i)];
}

} // namespace day

int main(int argc, wchar_t* argv[])
{               
    std::wcout << day::Tue + 3 << "\t" << day::GetName(day::Tue + 3) << std::endl;
    return 0;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜