日历分配

时间:2017-04-25 18:41:53

标签: c++

首先,让我通过打招呼来向大家致辞!这是我第一次使用这个资源(......可能不是我的最后一次)。话虽如此,我会尽力解释我的问题。这里没什么了......

该任务是使用c ++填充二维数组,给出一个月,一年和一周的日历,以便开始日历。我已经成功地从用户,年份和开始日期收集了天数(当月),但我无法理解如何正确填充2D数组而不获取读访问错误,如图所示:

" Calendar.exe中0x01288B7F处抛出异常:0xC0000005:访问冲突读取位置0x00290000。"

这里可以看到输出样本:

"输入月份:二月

输入年份:2016

输入星期几:星期六 一个 乙 d Ë F G 星期一星期二星期三星期四星期五星期六 ħ

8 9 10 11 12 13 14 H

15 16 17 18 19 20 21 H

22 16 17 18 19 20 21 H

22 23 24 25 26 27 28 H

29 23 24 25 26 27 28 H

29 23 24 25 26 7 1409053844 H

0 0 2130567168 7 -858993460 -858993460 -858993460 H

-858993460 3930364 -858993460 -858993460 3930360 -858993460 -858993460 H

3930364 -858993460 -858993460 -858993460 -858993460 -858993460 -858993460 H"

正如你所看到的那样,即使在它开始随地吐痰之前,它也会在结束时变得不稳定。

有问题的功能在这里:

void displayMonth(int leapRes, int start)
{
    int month[6][7] = { 0, 0 };

    cout << "F" << endl;

    for (int i = 0; i < 6; i++)
    {
        for (int j = month[i][j]; j < leapRes; j++)
        {
            month[i][j] = j;
        }
    }

    cout << "G" << endl;

    cout << "Sun Mon Tues Wed Thurs Fri Sat" << endl;

    for (int i = 0; i < 6; i++)
    {
        for (int j = month[i][start]; i < leapRes; j++)
        {
             if (j % 7 == 0) 
            {
                cout << "H" << endl;
                cout << "\n" << month[i][j] << " ";
            }
            else
                cout << month[i][j] << " ";
        }
    }
}

我可以对我提供的代码的任何部分提供进一步的解释。

再一次,对我来说不要太粗暴。我在其他地方找到了关于如何以最好的方式最好地完成这项任务的线索。

编辑:

我已经对功能代码进行了一些更改,虽然它使用正确的天数填充数组,但它既没有在正确的位置启动数组,也没有对齐到网格格式。

void displayMonth(int numDays, int start)
{
const int ROW = 6;
const int COL = 7;
int month[ROW][COL] = { 0, 0 };
int k = 1;

cout << "F" << endl;
//trying to populate the 2D array
for (int i = 0; i < ROW; i++)
{
    for (int j = 0; j < COL; j++)
    {
        month[i][j] = k;
        k++;
        //things like this are just bench checking
        cout << "this is position " << j << " in the array: " << month[i][j] 
<< endl;
        system("pause");
        //again, bench checking
        cout << "1" << endl;
        if (k >= numDays)
            break;
    }
}

cout << "G" << endl;

cout << "Sun Mon Tue Wed Thu Fri Sat" << endl;
//attempting to print said array
for (int i = 0; i < ROW; i++)
{
    for (int j = 0; j < COL; j++)
    {
        if (month[i][j] <= 0)
        {
            //cout << "2" << endl;
            cout << "---";
        }
        else
        {
            //cout << "3" << endl;
            cout << setw(3) << month[i][j] << " ";
        }
    }
}

1 个答案:

答案 0 :(得分:0)

在我看来,这是一个ctimestruct tm会派上用场的地方。将它包装在一个类(Month)中也是有帮助的。

要正确填充数组,您需要2个数据,第一天的工作日和总天数。对于第一个tm包含一个字段(tm_wday)。对于第二个,可以通过减去下个月第一天的年('tm_yday')与本月第一天的年份来计算。这具有自动允许闰年的优点。

声明数组时要记住的另一件事。一个月可以在日历中使用6周的部分时间。

由于我们需要两个tm对象,因此创建和填充结构的辅助函数会很有用。

由于大多数人更习惯将月份视为名称,但tm使用索引,map<string,int>将允许构造函数采用月份名称并有效地将其转换为索引,允许类存储名称以便稍后打印出来。

该课程可能如下所示:

#include <iostream>
#include <string>
#include <map>
#include <ctime>
#include <iomanip>

using std::cout;
using std::cin;
using std::string;
using std::map;
using std::ostream;
using std::setw;
class Month
{
    static const int MAX_WEEK_DAYS = 7;
    static const int MAX_WEEKS = 6;
    map<string,int> months =
    {
        {"January",0},
        {"February",1},
        {"March",2},
        {"April",3},
        {"May",4},
        {"June",5},
        {"July",6},
        {"Auguat",7},
        {"September",8},
        {"October",9},
        {"November",10},
        {"December",11}
    };
    string _name = "";
    int _days = 0;
    int _weeks[MAX_WEEKS][MAX_WEEK_DAYS];
    int _year = 0;
    void InitNewDate( int year , int month , int day,tm& date )
    {
        time_t rawTime;
        time( &rawTime );
        tm* tempDate = localtime(&rawTime);
        tempDate->tm_year = year - 1900;
        tempDate->tm_mon = month;
        tempDate->tm_mday = day;
        rawTime = mktime( tempDate );
        tempDate = localtime( &rawTime );
        date = *tempDate;
    }
public:
    Month(int year, string name)
    {
        _year = year;
        tm newDate;
        InitNewDate( year , months[name] , 1,newDate );
        tm tempDate;
        if ( months[name] == 12 )
        {
            InitNewDate( year + 1 , 0 , 1,tempDate );
        }
        else
        {
            InitNewDate( year , months[name] + 1 , 1,tempDate );
        }
        _days = tempDate.tm_yday - newDate.tm_yday;
        _name = name;
        int day = 1;
        for ( int i = newDate.tm_wday; i < 7; i++,day++ )
        {
            _weeks[0][i] = day;
        }
        for ( int week = 1; week < MAX_WEEKS; week++ )
        {
            for ( int j = 0; j < MAX_WEEK_DAYS && day <= _days; j++ , day++ )
            {
                _weeks[week][j] = day;
            }
        }

    }
    void PrintMonth( ostream& out )
    {
        out << _name << ", " << _year << '\n';
        out << "Sun Mon Tue Wed Thu Fri Sat\n";
        for ( int week = 0; week < MAX_WEEKS; week++ )
        {
            for ( int day = 0; day < MAX_WEEK_DAYS; day++ )
            {
                if ( _weeks[week][day] <= 0 )
                {
                    out << "--- ";
                }
                else
                {
                    out << setw( 3 ) << _weeks[week][day] << ' ';
                }
            }
            out << '\n';
        }
    }
};

构造函数将初始化所有变量,包括2D数组(Month m( 2016 , "February" );)。 PrintMonth功能将打印格式化的显示(m.PrintMonth(cout);)。

2016年2月的产出:

February, 2016
Sun Mon Tue Wed Thu Fri Sat
---   1   2   3   4   5   6
  7   8   9  10  11  12  13
 14  15  16  17  18  19  20
 21  22  23  24  25  26  27
 28  29 --- --- --- --- ---
--- --- --- --- --- --- ---