C ++月,日和年验证

时间:2016-03-25 22:33:12

标签: c++ date

我正在为我的C ++编程类简介做一个项目。该项目要求用户使用mm / dd / yyyy格式输入日期。根据给出的信息,程序必须确定日期是有效还是无效,然后显示对该日期的响应。我正面临着目前所有问题都出现的问题“好日子!”我不确定问题出在哪里。任何帮助表示赞赏。如果你能帮我指出正确的方向,那就太棒了。

#include <iostream>
#include <conio.h>

using namespace std;

void getDate(int *month, int *day, int *year);
int checkDate(int month, int day, int year);
void displayMessage(int status);

int main()
{
    int month, day, year;
    int s = 0;

    getDate(&month, &day, &year);
    do
    {
        checkDate(month, day, year);
        displayMessage(s);
        getDate(&month, &day, &year);
    } 
    while (_getch() != EOF);
}

void getDate(int *month, int *day, int *year)
{
    char fill;
    fill = '/';
    cout << "Enter a date in mm/dd/yyyy form: ";
    cin >> *month;
    if (cin.get() != '/')
    {
        cout << "expected /" << endl;
    }
    cin >> *day;
    if (cin.get() != '/')
    {
        cout << "expected /" << endl;
    }
    cin >> *year;
    cout << *month << fill << *day << fill << *year << endl;
};

int checkDate(int month, int day, int year)
{
    if ((month = 1) || (month = 3) || (month = 5) || (month = 7) ||
        (month = 8) || (month = 10) || (month = 12))
    {
        day <= 31;
    }
    else if ((month = 4) || (month = 6) || (month = 9) || (month = 11))
    {
        day <= 30;
    }
    else if ((month = 2) && (year % 4 == 0))
    {
    day <= 29;
    }
    else if ((month = 2) && (year % 4 != 0))
    {
        day <= 28;
    };
    int status = 0;
    if ((year < 999) || (year > 10000))
    {
        status == 1;
    }
    if ((month < 1) || (month > 12))
    {
        status == 2;
    }
    else if ((day < 1) || (day > 31))
    {
        status == 3;
    }
    else if ((day < 1) || (day > 30))
    {
        status == 4;
    }
    else if ((day < 1) || (day > 29))
    {
        status == 5;
    }
    else if ((day < 1) || (day > 28))
    {
        status == 6;
    }
    return status;
};

void displayMessage(int status)
{
    if (status == 0)
    {
        cout << "Good date!" << endl;
    }
    if (status == 1)
    {
        cout << "Bad year" << endl;
    }
    if (status == 2)
    {
        cout << "Bad month" << endl;
    }
    if (status == 3)
    {
        cout << "Bad day. Not 1-31" << endl;
    }
    if (status == 4)
    {
        cout << "Bad day, not 1-30" << endl;
    }
    if (status == 5)
    {
        cout << "Bad day, not 1-29" << endl;
    }
    if (status == 6)
    {
        cout << "Bad day, not 1-28" << endl;
    }
    _getch();
}

5 个答案:

答案 0 :(得分:2)

1)这里有几个问题,但最明显的问题是main()

int s=0; 
...
    checkDate(month, day, year);   // you don't store the status
    displayMessage(s);             // so s will always be 0 ! So good date !

你必须纠正这个:

    s=checkDate(month, day, year); // store the result of the check        
    displayMessage(s);             // and take it to display the message  

2)然后在checkDate()中,混合====将变量的值更改为左侧。 ==只进行比较但不存储任何内容。在纠正/调整时,无需任何优化,您的代码应如下所示:

int checkDate(int month, int day, int year)
{
    int status=0; 

    if ((month == 1 || month == 3 || month == 5 || month == 7 ||
        month == 8 || month == 10 || month == 12) && ( day>31 || day<1) )
    {
        status = 3; 
    }
    else if ((month == 4 || month == 6 || month == 9 || month == 11) && (day>30 || day<1) )
    {
        status = 4; 
    }
    else if ((month == 2) && (year % 4 == 0) && (day>29 || day<1))
    {
        status = 5; 
    }
    else if ((month == 2) && (year % 4 != 0) && (day>28 || day<1) )
    {
        status = 6; 
    }
    else if ((year < 999) || (year > 10000))
    {
        status = 1;
    }
    if ((month < 1) || (month > 12))
    {
        status = 2;
    }
    return status;
};

3)在此之后,你应该改进输入功能,因为:

  • 它无法处理无效的分隔符。如果缺少“/”,则会显示错误消息,但您继续输入,就好像一切都很好。
  • 它不能处理无效(即非数字)输入。例如,如果用户输入XI / 1/2016,则输入将失败。

请注意,(cin>>xxx)是一个可以在if中使用的表达式,如果所有内容都已正确读取,则为真。还要注意cin.clear()清除失败后阻止输入的错误标志。

答案 1 :(得分:0)

更紧凑,更简洁的checkDate(按值替换大写返回)

int checkDate(int day, int month, int year) {
    if(day < 1 || day > 31) {
        return BADVALUE;
    } else if(month < 1 || month > 12) {
        return BADVALUE;
    } else if (year < MINYEAR || year > MAXYEAR) {
        return YEAROUTRANGE;
    }

    if ((month == 4 || month == 6 || month == 9 || month == 11) && day == 31) {
        return BADMONTHDAY; 
    } else if ((month == 2) && (year % 4 == 0) && day > 29) {
        return BADMONTHYEAR;

    } else if ((month = 2) && (year % 4 != 0) && day > 28) {
        return BADMONTHYEAR; 
    }
    return GOOD;
}

答案 2 :(得分:0)

这也可以通过正则表达式实现吗?

我知道这种方法有很多缺点,但仍然可以考虑:

#include <regex>
#include <string>

using std::regex;
using std::regex_match;
using std::string;

// for ddmmyy
regex ddmmyy("^([0-2][0-9]|(3)[0-1])(((0)[0-9])|((1)[0-2]))\\d{2}$");

/* 
   for dd/mm/yy https://regex101.com/r/IqPLBJ/1
   for dd/mm/yyyy - could start from \\d{4}$ instead of \\d{2}$ bearing 0000-case in mind
*/
regex slashed_ddmmyy("^([0-2][0-9]|(3)[0-1])\/(((0)[0-9])|((1)[0-2]))\/\\d{2}$"); 

string f1 = "111223";
bool res = regex_match(f1,ddmmyy); // true

f1 = "112223";
res = regex_match(f1,ddmmyy); // false

res = regex_match(f1, slashed_ddmmyy); // false, no slashes

答案 3 :(得分:0)

您还可以使用函数mktime()

它将尝试将给定的tm结构转换为正确的日期。如果随后对该结构的单个成员的比较显示所有成员均相等,则给定的tm结构包含有效日期。

bool CBorrow::validateDate(tm * timestruct)
{
    struct tm copy;
    copy.tm_sec = timestruct->tm_sec;
    copy.tm_min = timestruct->tm_min;
    copy.tm_hour = timestruct->tm_hour;
    copy.tm_mday = timestruct->tm_mday;
    copy.tm_mon = timestruct->tm_mon;
    copy.tm_year = timestruct->tm_year;
    copy.tm_wday = timestruct->tm_wday;
    copy.tm_yday = timestruct->tm_yday;
    copy.tm_isdst = timestruct->tm_isdst;

    time_t res = mktime(&copy);
    if (res < 0)
    {
        return false;
    }
    if (copy.tm_mday != timestruct->tm_mday
     || copy.tm_mon != timestruct->tm_mon
     || copy.tm_year != timestruct->tm_year)
    {
        return false;
    }
    return true;
}

答案 4 :(得分:0)

更新了 C++20 的答案:

#include <chrono>
#include <iostream>

void
displayMessage(std::chrono::year_month_day ymd)
{
    using namespace std;
    using namespace std::chrono;
    if (!ymd.year().ok())
    {
        cout << "Bad year\n";
        return;
    }
    if (!ymd.month().ok())
    {
        cout << "Bad month\n";
        return;
    }
    if (!ymd.ok())
    {
        cout << "Bad day, not 1-" << (ymd.year()/ymd.month()/last).day() << '\n';
        return;
    }
    cout << "Good date!\n";
}

int
main()
{
    using namespace std::literals;
    displayMessage(29d/2/1900);
}

输出:

Bad day, not 1-28

(1900 年不是闰年)