0

I need to print out dates in four formats when a user enters a month, day and year. For example if I enter "sept" for month, 17 for day and 1921 for year, it will print out:

1) 9/17/1921
2) September 17,1921
3) 1921-9-17
4) 1921-sep-17

I also do validation where if the number of days is less than 1 or greater than than the number of days for that month and the year cannot be less than 1900 or greater than 2020. If it is, month gets defaulted to "January" day to 1 and year to 2001.

When I enter jan for month 5 for day 2005 for year, I get weird values in my console 1/-858993460/-858993460 and then terminates. But when I enter mar 5 2005 i get

3/5/2005
March2005
ory corruption5
ory corruptionmar-5

I create an instance of Date and call a 3 argument constructor. The 3 argument constructor then calls a validate function which return a boolean. If the return value is false, it will call the default constructor which sets everything to january 1 2001.

//UPDATE: Changed inital value of int index in date.cpp to -1 instead of NULL. Doing this now calls the print function four times four when I enter "jan" but I still get the weird results

1/5/2005
January2005 //This should be January 5, 2005
ory corruption5 
ory corruptionmar-5

Why does the first time print is called all my member variables retain the values, but the 2nd, 3rd, and 4th time, day is missing and shows weird corruption message? I don't know what is going on but when I also enter an invalid date such as "jan" for month but 36 for days and 2025 for year, the default constructor should set month to January, day to 1 and year to 2001 but I get garbage values

1/-858993460/-858993460

This is the first time print is called then after that it terminates.

//Header

#pragma once
#include <iostream>
#include <string>
using namespace std;

/*Add more constants if needed*/
#ifndef DATE_H
#define DATE_H

enum DateFormat { mdy1, mdy2, ymd1, ymd2 };
const int MIN_YEAR = 1900;
const int MAX_YEAR = 2020;
const string monthStr[] =   //alternative:  const char monthStr[] [15]=
{ "January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November",
"December" };
const string monthStrAbbrev[] =  //not strictly necessary, but helpful
{ "jan", "feb", "mar", "apr", "may", "jun",
"jul", "aug", "sep", "oct", "nov",
"dec" };
const int monthDays[] =
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };


class Date {
private:
    string month;
    int day, year;
    bool validateDate(string, int, int);
    Date();
public:
    Date(string, int, int);
    void print(DateFormat type);
};
#endif // !DATES_H

//Dates.cpp

#include "stdafx.h"
#include <iostream>
#include <algorithm>

#include "date.h"
using std::cout;
using std::cin;
int global;

Date::Date() : month("January"), day(1), year(2001) { cout << "INSIDE CONST" << endl; }

Date::Date(string m, int d, int y) 
{
    if (!validateDate(m, d, y))
    {
        cout << "IF FALSE" << endl;
        Date();
    }
    else
    {
        month = m;
        day = d;
        year = y;
        cout << "MONTH IS :" << month << " DAY IS: " << day << " YEAR IS: " << year << endl;
    }
}

bool Date::validateDate(string m, int d, int y)
{
    cout << "size is " << sizeof(monthStrAbbrev) / sizeof(monthStrAbbrev[0]) << endl;;
    int index = -1;

    for (int x = 0; x < 11; x++)
    {
        string mAbr = monthStr[x].substr (0, 3);
        transform(mAbr.begin(), mAbr.end(), mAbr.begin(), (int(*) (int)) tolower);
        cout << "Abbr: " << mAbr << endl;
        if (m == mAbr)
        {
            index = x;
            global = x;
            cout << "x " << x << " global " << global << " Index " << index << endl;
            if (d < 1 && d > monthDays[index])
            {
                cout << "FALSE 1" << endl;
                return false;
            }
            if (y < MIN_YEAR || y > MAX_YEAR)
            {
                cout << "FALSE 2" << endl;
                return false;
            }

            break;
        }
    }
    if (index == -1)
    {
        cout << "IF NULL" << endl;
        return false;
    }
    else
    {
        cout << " IF NOT NULL" << endl;
        return true;
    }
}

void Date::print(DateFormat type)
{
    if (type == mdy1)
    {
        cout << global + 1 << "/" << day << "/" << year << endl;
    }
    else if (type == mdy2)
    {
        cout << monthStr[global] << day + ", " << year << endl;
    }
    else if (type == ymd1)
    {
        cout << year + "-" << (global + 1) + "-" << day << endl;
    }
    else if (type == ymd2)
    {
        cout << year + "-" << month + "-" << day << endl;
    }
}

//Test.cpp

#include "stdafx.h"

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
#include "date.h"


void setDateValues(string&, int&, int&);
int main()
{
    string mth;
    int  day, yr;

    setDateValues(mth, day, yr);
    transform(mth.begin(), mth.end(), mth.begin(), (int(*) (int)) tolower);

    Date d1(mth, day, yr);
    cout << "Date is:\n";
    DateFormat type;
    type = mdy1;
    d1.print(type);
    type = mdy2;
    d1.print(type);
    type = ymd1;
    d1.print(type);
    type = ymd2;
    d1.print(type);
    return 0;
}

void setDateValues(string & m, int& d, int& y)
{
    cout << "Enter month: ";
    cin >> m;
    cout << "Enter day: ";
    cin >> d;
    cout << "Enter year: ";
    cin >> y;
}
henhen
  • 1,038
  • 3
  • 18
  • 36
  • 1
    You are missing `#endif` at the end of `date.h`, you are initializing an `int` to `NULL` (e.g. `int index = NULL;`), you are comparing `int` to `NULL`, (e.g. `if (index == NULL)`), and you have an assignment instead of a comparison `else if (type = ymd2)`. Don't you read the warnings? (those need fixing, but will not correct your logic errors) – David C. Rankin Jun 24 '18 at 02:12
  • sorry, I forgot to add that to snippet, but I had the #endif. Also, index is set to NULL but inside the loop, it gets reassigned a value, which makes it not NULL right? – henhen Jun 24 '18 at 02:15
  • Stack Overflow isn't a free debugging service, and you should show your attempts at debugging the code with a debugger or other simpler methods such as debug print statements. This won't be the only time you end up with a bug in your code, and learning to debug your programs will help you much more than having someone find the bug for you. http://idownvotedbecau.se/nodebugging/ – eesiraed Jun 24 '18 at 02:45
  • -858993460 is 0xFFFFFFFFCCCCCCCC in hexadecimal. It's probably a magic debugging value for an uninitialized variable or something. Also, `using namespace std` is [bad practice](https://stackoverflow.com/q/1452721/9254539), especially when you put it in a header. – eesiraed Jun 24 '18 at 02:46
  • I dont know if this is a problem, but when I create a new console application in V Studio 2017, it automatically creates a header file and cpp file with the main in it. The name of the files are both date in this case. But I like to have test.cpp so I renamed the auto created date cpp file with main() to test cpp and created a separate date cpp implementation file. I am also aware I should just st import whatever I need from std namespace such as using std::cout etc but did not think it would be an issue. – henhen Jun 24 '18 at 04:56

1 Answers1

3

There is a standard library function for this: strftime().

You give it a date in a struct, and it writes a string. For your four cases, the format strings would be:

1) %m/%d/%Y
2) %B %d, %Y
3) %F
4) %Y-%b-%d
John Zwinck
  • 239,568
  • 38
  • 324
  • 436