我正在为我的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();
}
答案 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)在此之后,你应该改进输入功能,因为:
请注意,(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(©);
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 年不是闰年)