我正在尝试用c ++编写一个简单的程序,它返回给定日期的星期几.
输入格式为日,月,年.我无法让它与闰年一起工作.a当输入年是闰年时,我尝试从变量中减去一个,但程序最终崩溃而没有错误消息.
我会感激任何建议,但请尽量保持简单,我仍然是一个初学者.对于这个愚蠢的问题道歉,请原谅我的错误,这是我第一次在这个网站上发帖.
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
using namespace std;
int d;
int m;
int y;
string weekday(int d, int m, int y){
int LeapYears = (int) y/ 4;
long a = (y - LeapYears)*365 + LeapYears * 366;
if(m >= 2) a += 31;
if(m >= 3 && (int)y/4 == y/4) a += 29;
else if(m >= 3) a += 28;
if(m >= 4) a += 31;
if(m >= 5) a += 30;
if(m >= 6) a += 31;
if(m >= 7) a += 30;
if(m >= 8) a += 31;
if(m >= 9) a += 31;
if(m >= 10) a += 30;
if(m >= 11) a += 31;
if(m == 12) a += 30;
a += d;
int b = (a - 2) % 7;
switch (b){
case 1:
return "Monday";
case 2:
return "Tuesday";
case 3:
return "Wednesday";
case 4:
return "Thursday";
case 5:
return "Friday";
case 6:
return "Saturday";
case 7:
return "Sunday";
}
}
int main(){
cin >> d >> m >> y;
cout << weekday(d, m, y);
}
Run Code Online (Sandbox Code Playgroud)
第一:如果已经存在可以处理相同问题的标准化功能,则不要编写自己的功能.重点是你可能很容易犯错误(我已经可以在你的weekday()功能的第一行看到一个错误),而标准化功能的实现已经过彻底的测试,你可以确信他们提供了你的结果期待得到.
话虽这么说,这是一个使用std :: localtime和std :: mktime的可能方法:
#include <ctime>
#include <iostream>
int main()
{
std::tm time_in = { 0, 0, 0, // second, minute, hour
9, 10, 2016 - 1900 }; // 1-based day, 0-based month, year since 1900
std::time_t time_temp = std::mktime(&time_in);
//Note: Return value of localtime is not threadsafe, because it might be
// (and will be) reused in subsequent calls to std::localtime!
const std::tm * time_out = std::localtime(&time_temp);
//Sunday == 0, Monday == 1, and so on ...
std::cout << "Today is this day of the week: " << time_out->tm_wday << "\n";
std::cout << "(Sunday is 0, Monday is 1, and so on...)\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
老问题的新答案,因为它们正在改变的工具......
C++20 规范表示以下内容将具有与问题中代码的意图相同的功能:
#include <chrono>
#include <format>
#include <iostream>
int
main()
{
using namespace std;
using namespace std::chrono;
year_month_day dmy;
cin >> parse("%d %m %Y", dmy);
cout << format("{:%A}", weekday{dmy}) << '\n';
}
Run Code Online (Sandbox Code Playgroud)
今天,人们可以通过使用这个免费的开源日期/时间库来试验这种语法,只不过日期对象位于namespace date而不是中namespace std::chrono,并且格式字符串的语法略有改变。
#include "date/date.h"
#include <iostream>
int
main()
{
using namespace std;
using namespace date;
year_month_day dmy;
cin >> parse("%d %m %Y", dmy);
cout << format("%A", weekday{dmy}) << '\n';
}
Run Code Online (Sandbox Code Playgroud)
小智 6
您对闰年的理解是错误的:
闰年是每4年EXCEPT如果它是整除100,但即便如此,它仍然是一个闰年,如果它是被400整除。
可以在此处找到有关如何计算“天数”(dn) 的清晰简明的说明。
获得天数 (dn) 后,只需执行模数 7。结果将是星期几 (dow)。
这是一个示例实现(不检查日期是否为有效输入):
#include <iostream>
#include <iomanip>
typedef unsigned long ul;
typedef unsigned int ui;
// ----------------------------------------------------------------------
// Given the year, month and day, return the day number.
// (see: https://alcor.concordia.ca/~gpkatch/gdate-method.html)
// ----------------------------------------------------------------------
ul CalcDayNumFromDate(ui y, ui m, ui d)
{
m = (m + 9) % 12;
y -= m / 10;
ul dn = 365*y + y/4 - y/100 + y/400 + (m*306 + 5)/10 + (d - 1);
return dn;
}
// ----------------------------------------------------------------------
// Given year, month, day, return the day of week (string).
// ----------------------------------------------------------------------
std::string CalcDayOfWeek(int y, ul m, ul d)
{
std::string day[] = {
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday",
"Monday",
"Tuesday"
};
ul dn = CalcDayNumFromDate(y, m, d);
return day[dn % 7];
}
// ----------------------------------------------------------------------
// Program entry point.
// ----------------------------------------------------------------------
int main(int argc, char **argv)
{
ui y = 2017, m = 8, d = 29; // 29th August, 2017.
std::string dow = CalcDayOfWeek(y, m, d);
std::cout << std::setfill('0') << std::setw(4) << y << "/";
std::cout << std::setfill('0') << std::setw(2) << m << "/";
std::cout << std::setfill('0') << std::setw(2) << d << ": ";
std::cout << dow << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
您可以使用公历日期系统从升压C ++库找到一个给定日期的一周中的一天。这是一个简单的例子:
#include <boost/date_time.hpp>
#include <string>
#include <iostream>
const static std::string daysOfWeek[] = {
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
};
int getDayOfWeekIndex(int day, int month, int year) {
boost::gregorian::date d(year, month, day);
return d.day_of_week();
}
int main()
{
const int index = getDayOfWeekIndex(30, 07, 2018);
std::cout << daysOfWeek[index] << '\n';
}
Run Code Online (Sandbox Code Playgroud)
此代码打印Monday.
当一个数能被 7 整除时会发生什么?
14 / 7 = 2 14% 7 = 0
模运算符 (% n) 将返回 0 到 n -1 之间的数字
如果 n 除以 7 余数永远不可能是 7 所以
int b = (a - 2) % 7;
switch (b){
case 1:
return "Monday";
case 2:
return "Tuesday";
case 3:
return "Wednesday";
case 4:
return "Thursday";
case 5:
return "Friday";
case 6:
return "Saturday";
case 7:
return "Sunday";
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,它永远不可能是星期日
尝试这个
int b = (a - 2) % 7;
switch (b){
case 0:
return "Sunday";
case 1:
return "Monday";
case 2:
return "Tuesday";
case 3:
return "Wednesday";
case 4:
return "Thursday";
case 5:
return "Friday";
case 6:
return "Saturday";
default:
return "Error";
}
Run Code Online (Sandbox Code Playgroud)