Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C+的日历程序+;这个班有一个计日错误 我正在制作一个C++程序,它通过计算1753年1月1日的一天的天数来确定一年中的一天的月份。然后,它将天数除以7,以确定用于计算月的第一天从哪一天开始的“偏移量”(例如:由于1753年1月1日是星期一,因此偏移量为2表示月的第一天是星期三)。当我注意到一个非常奇怪的bug时,我完成了我的代码并运行了几次测试。对于2000年,抵消比它应该的高一倍(2月从周三开始,而不是周二,等等)。这个问题在任何其他闰年或以“00”结尾的年份中都不存在。这是我唯一一次失败的测试,而就我的一生而言,我似乎都不知道问题出在哪里_C++ - Fatal编程技术网

C+的日历程序+;这个班有一个计日错误 我正在制作一个C++程序,它通过计算1753年1月1日的一天的天数来确定一年中的一天的月份。然后,它将天数除以7,以确定用于计算月的第一天从哪一天开始的“偏移量”(例如:由于1753年1月1日是星期一,因此偏移量为2表示月的第一天是星期三)。当我注意到一个非常奇怪的bug时,我完成了我的代码并运行了几次测试。对于2000年,抵消比它应该的高一倍(2月从周三开始,而不是周二,等等)。这个问题在任何其他闰年或以“00”结尾的年份中都不存在。这是我唯一一次失败的测试,而就我的一生而言,我似乎都不知道问题出在哪里

C+的日历程序+;这个班有一个计日错误 我正在制作一个C++程序,它通过计算1753年1月1日的一天的天数来确定一年中的一天的月份。然后,它将天数除以7,以确定用于计算月的第一天从哪一天开始的“偏移量”(例如:由于1753年1月1日是星期一,因此偏移量为2表示月的第一天是星期三)。当我注意到一个非常奇怪的bug时,我完成了我的代码并运行了几次测试。对于2000年,抵消比它应该的高一倍(2月从周三开始,而不是周二,等等)。这个问题在任何其他闰年或以“00”结尾的年份中都不存在。这是我唯一一次失败的测试,而就我的一生而言,我似乎都不知道问题出在哪里,c++,C++,代码如下: //********************************************************************** #include <iostream> #include <iomanip> using namespace std; int getYear(); int getMonth(); int computeNumDays(int month, int year); int computeOffset(int mont

代码如下:

//**********************************************************************
#include <iostream>
#include <iomanip>
using namespace std;

int getYear();
int getMonth();
int computeNumDays(int month, int year);
int computeOffset(int month, int year);
bool isLeapYear(int year);
void displayHeading(int month, int year);
void displayTable(int offset, int numDays);
/********************
* MAIN
*********************/
int main()
{
   int month = getMonth();
   int year = getYear();
   int offset = computeOffset(month, year);
   int numDays = computeNumDays(month, year);
   displayHeading(month, year);
   displayTable(offset, numDays);
   return 0;
}
/********************
*GETMONTH
*Prompts the user for a month number
*********************/
int getMonth()
{
   int month;
//Month number must be between 1 and 12
   cout << "Enter a month number: ";
   cin >> month;
//Displays an error message if the month is under 1 or over 12
   while (month < 1 || month > 12)
   {
      cout << "Month must be between 1 and 12.\n";
      cout << "Enter a month number: ";
      cin >> month;
   }
   return month;
}
/********************
*GETYEAR
* prompts the user for a year
*********************/
int getYear()
{
   int year;
   cout << "Enter year: ";
   cin >> year;
//Displays an error message if the year is less than 1753
   while (year < 1753)
   {
      cout << "Year must be 1753 or later.\n";
      cout << "Enter year: ";
      cin >> year;
     
   }
   cout << "\n";
   return year;
}
/********************
*COMPUTENUMDAYS
* For computing the number of days in a month, so we know where to count to when filling in
* the calendar
*********************/
int  computeNumDays(int month, int year)
{
int numDays; 
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)
   return numDays = 31;
else if (month == 4 || month == 6 || month == 9 || month == 11)
   return numDays = 30;
else if (month == 2 && (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
   return numDays = 29;
else if (month == 2)
   return numDays = 28;
}

/*********************
*COMPUTEOFFSET
*********************/
int computeOffset(int month, int year)
{
   int totalYearDays = 0;
   int totalMonthDays = 0;
//This counts up all the days between the January 1st of 1753 to January 1st of the users input
//year. Leap years are accounted for with the IF statements and the isLeapYear function
   for (int yearCount = 1753; yearCount < year; yearCount++)
   {
      if (isLeapYear(yearCount))
         totalYearDays += 366;
      else
         totalYearDays += 365;
   }
//The days of the month of the user input year are added up here. If the user inputs February(2),
//then it counts the days of each month in between and adds them up. 
   for (int monthCount = 0; monthCount < month; monthCount++)
   {
      if (monthCount == 1 || monthCount == 3 || monthCount == 5)
         totalMonthDays += 31;
      else if (monthCount == 7 || monthCount == 8 || monthCount == 10 || monthCount == 12)
         totalMonthDays += 31;
      else if (monthCount == 4 || monthCount == 6 || monthCount == 9 || monthCount == 11)
         totalMonthDays += 30;
//if the user input year is a leap year, then an extra day to February is added
      else if (monthCount == 2 && (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
            totalMonthDays += 29;
      else if (monthCount == 2)
            totalMonthDays += 28;
   }
   int offset = (totalYearDays + totalMonthDays) % 7;
   return offset;
}
/******************************************
* ISLEAPYEAR
******************************************************/
bool isLeapYear(int yearCount)
{
//Equation for determining if a year is a leap year or not
   if ((yearCount % 4 == 0 && yearCount % 100 != 0) || (yearCount % 400 == 0))
      return true;
   else
      return false;
}
/*************************************************
*DISPLAYHEADING
* This is where the Month Name and Year are shown
**************************************************/
void displayHeading(int month, int year)
{
if (month == 1)
   cout << "January, " << year << endl;
else if (month == 2)
   cout << "February, " << year << endl;
else if (month == 3)
   cout << "March, " << year << endl;
else if (month == 4)
   cout << "April, " << year << endl;
else if (month == 5)
   cout << "May, " << year << endl;
else if (month == 6)
   cout << "June, " << year << endl;
else if (month == 7)
   cout << "July, " << year << endl;
else if (month == 8)
   cout << "August, " << year << endl;
else if (month == 9)
   cout << "September, " << year << endl;
else if (month == 10)
   cout << "October, " << year << endl;
else if (month == 11)
   cout << "November, " << year << endl;
else if (month == 12)
   cout << "December, " << year << endl;

return;
}

/********************
*DISPLAYTABLE
*********************/
void displayTable(int offset, int numDays)
{
   //days of the week are displayed here
   cout << setw(4) << "Su" << setw(4) << "Mo" << setw(4) << "Tu"
      << setw(4) << "We" << setw(4) << "Th" << setw(4) << "Fr" << setw(4)
      << "Sa" << setw(2) << endl;
//WeekBreak counter will be used to add new lines for each week
   int weekBreak = 1;
   //This IF statement determines the number of days before the first of the month occurs,
   // as well as sets the weekBreak counter
   if (offset != 6 && offset >= 0)
      do
      {
         cout << setw(4) << "  ";
         offset--;
         weekBreak++;
      }    while (offset != -1);

      //The counter loop here begins putting in the dates, all the way from the first to
//the max number of days in the month
      for (int date = 1; date <= numDays; date++)
      {
         cout << "  " << setw(2) << date;
         weekBreak++; //weekBreak prevents us from putting more than 
                      //7 dates in a single week
         if (weekBreak == 8)
         {
            cout << "\n"; //once a week hits 7 dates(or 8 spaces), it moves on to a new week
            weekBreak = 1;
         }
      }
      //this puts an end to the calander, regardless if weekBreak limit is reached
      if (weekBreak >= 2 && weekBreak <= 7)
         cout << "\n";

}
//**********************************************************************
#包括
#包括
使用名称空间std;
int getYear();
int getMonth();
整数计算日(整数月,整数年);
整数计算偏移量(整数月,整数年);
布尔群岛年(国际年);
无效显示标题(整数月,整数年);
void displayTable(int offset,int numDays);
/********************
*主要
*********************/
int main()
{
int month=getMonth();
int year=getYear();
int offset=计算偏移量(月、年);
int numDays=计算天数(月、年);
显示标题(月、年);
显示表(偏移量,numDays);
返回0;
}
/********************
*GETMONTH
*提示用户输入月份号
*********************/
int getMonth()
{
整月;
//月数必须介于1和12之间
月份;
//如果月份小于1或大于12,则显示错误消息
而(月<1 | |月>12)
{
月份;
}
返回月份;
}
/********************
*假期
*提示用户一年
*********************/
整年
{
国际年;
年份;
//如果年份小于1753,则显示错误消息
而(年份<1753年)
{
过去一年;
}

cout为了调试代码,我编写了以下
main
函数:

int main()
{
    for (int year = 1753; year <= 2021; year++)
    {
        for (int month = 1; month <= 12; month++)
        {
            int offset = computeOffset(month, year);
            int numDays = computeNumDays(month, year);

            std::chrono::year_month_day date(std::chrono::year(year), std::chrono::month(month), std::chrono::day(1));
            std::chrono::weekday day{ std::chrono::sys_days(date) };
            int expectedOffset = ((day - std::chrono::Monday).count() + 7) % 7;
            if (expectedOffset != offset)
            {
                std::cout << year << "/" << month << " expected " << expectedOffset << " actual " << offset << "\n";
            }
        }
    }
    return 0;
}
计算偏移量

    else if (month == 2 && isLeapYear(year))
        return numDays = 29;
        else if (monthCount == 2 && isLeapYear(year))
            totalMonthDays += 29;
修复了这个bug

该错误的原因实际上是两个错误的组合:

  • computeOffset
    monthCount
    中,从
    0
    开始,而不是
    1
  • year%400==0
    为真时,表达式
    monthCount==2&&(year%4==0&&year%100!=0)|(year%400==0)
    将始终为
    true
  • 这会导致
    totalMonthDays
    的值比它在
    %7
    之后可以被400整除的年份多29,这会导致
    computeOffset
    的结果比它应该的值高1

    通过消除重复,您的代码可以大大简化:

    int computeNumDays(int month, int year)
    {
        switch (month)
        {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            return 31;
        case 4:
        case 6:
        case 9:
        case 11:
            return 30;
        case 2:
            return isLeapYear(year) ? 29 : 28;
        default:
            throw std::invalid_argument("invalid month");
        }
    }
    
    int computeOffset(int month, int year)
    {
        int totalYearDays = 0;
        int totalMonthDays = 0;
        //This counts up all the days between the January 1st of 1753 to January 1st of the users input
        //year. Leap years are accounted for with the IF statements and the isLeapYear function
        for (int yearCount = 1753; yearCount < year; yearCount++)
        {
            if (isLeapYear(yearCount))
                totalYearDays += 366;
            else
                totalYearDays += 365;
        }
        //The days of the month of the user input year are added up here. If the user inputs February(2),
        //then it counts the days of each month in between and adds them up. 
        for (int monthCount = 1; monthCount < month; monthCount++)
        {
            totalMonthDays += computeNumDays(monthCount, year);
        }
        int offset = (totalYearDays + totalMonthDays) % 7;
        return offset;
    }
    
    bool isLeapYear(int yearCount)
    {
        //Equation for determining if a year is a leap year or not
        if ((yearCount % 4 == 0 && yearCount % 100 != 0) || (yearCount % 400 == 0))
            return true;
        else
            return false;
    }
    
    int计算天数(int月,int年)
    {
    开关(月)
    {
    案例1:
    案例3:
    案例5:
    案例7:
    案例8:
    案例10:
    案例12:
    返回31;
    案例4:
    案例6:
    案例9:
    案例11:
    返回30;
    案例2:
    返回年份?29:28;
    违约:
    抛出std::无效的_参数(“无效月份”);
    }
    }
    整数计算偏移量(整数月,整数年)
    {
    int totalYearDays=0;
    int totalMonthDays=0;
    //这将统计1753年1月1日到用户输入的1月1日之间的所有天数
    //年份。闰年使用IF语句和isLeapYear函数进行计算
    对于(int yearCount=1753;yearCount
    我建议您开始阅读它所提供的内容。建议:备份您所拥有的内容并删除所有用户输入。用您知道的导致您正在查找的错误的硬编码值替换它。这减少了实验的周期时间,并使每个人都使用相同的数据集,希望使用相同的错误。Doe您的代码考虑到可被100整除的年份不是闰年,但可被400整除的年份是闰年吗?我不喜欢
    if else if
    ladders。使用字符串数组:
    char*month\u name[]={“无”、“一月”、“二月”、“三月”、“十二月”};std::cout+1用于使用C++20 chrono编写调试代码。Fwiw,这里是C++20 chrono(在C++20 date.h之前)打印日历:。基于计时的代码的一大优点是没有实现
    computeOffset
    的循环。这个功能可以在
    print\u of u calendar\u month
    case 2
    string(static\u cast((wd firstdow).count()*3',
    中找到。更简单地说,就是子表达式
    (wd firstdow).count()
    。计算从
    firstdow
    (星期日)到每月第一天的天数。