武汉纺织大学课程设计报告书武汉纺织大学课程设计报告书名称C++程序设计课程设计题目万年历专业班级指导教师李敏2014 年6月11 日第1 页共24 页目录课程设计报告书 (1)第一章需求分析 (3)第二章概要设计 (4)第三章详细设计与编码 (5)第四章调试分析 (13)第五章用户使用说明 (144)设计心得 (15)参考文献 (166)致谢 (16)第2 页共24 页第一章需求分析如今的社会是一个信息的时代,随着电脑等科技产品在人们生活中占据着越来越重要的地位,人们就会越加的善加利用,这为我们的生活带来了极大的效率,同时计算机的普及更可以看出它所占的地位。
万年历作为日常中的一种小工具,它具有多方面的小工能,主要在日期的显示上给人以直观的表达效果,在日期的查询上方便简洁,还有就是在某些节日的提醒上都给我们带来极大的方便,是一种比较实用的小工具。
我们每个人都可以在自己的个人电脑上进行制作,一方面不仅可以加强巩固我们对C++语言的学习,还可以通过自主的编程找到自身的缺点。
这对培养我们自身的创新能力和动手能力具有很大的作用。
第二章概要设计1.设计要求①模仿现实生活中的挂历.②当前页以系统当前日期的月份为准显示当前月的每一天(显示出日及对应的星期几).③当系统日期变到下一月时,系统自动翻页到下一月.2.总体设计<1>实现操作流程图第三章详细设计与编码<1>设计思路要输出一个月的月历。
第一要输出一行星期,这个很简单就可以实现,第二要知道一个月的一号是星期几,为了知道它,必须有一个日历的开始时间,我在这里设定的是1970年1月1号,此时它对应的事星期四,然后要计算你输入的日期与开始日期的总天数totaldays,(totaldays+4)%7即可得到月头是星期几,然后为了判断用户输入的日期是否正确,还得有一个检测判断函数,然后关于第三个功能—实时时钟显示的实现思想为:每隔一秒输出系统当前时钟,每次输出时要在第一排的最前面输出,以覆盖掉上次输出的时钟,给人像是时钟自己在变化,我们可以调用系统API函数SetConsoleCursorPosition()来控制光标位置,整体思路如上所述。
<2>每个模块实现详解㈠Calendar类的实现,具体代码如下class Calendar{public:Calendar(){string p;t=time(0);p=getYear();year=atoi(p.c_str()); //将从系统时间中提取的字符串转换为整数p=getDay();day=atoi(p.c_str());p=getMonth();month=convert(p);// cout<<ctime(&t);}Calendar(int y,int m,int d){long a;year=y;month=m;day=d;a=getTotalDay();a=a*24*3600;t=a;}int convert(string p);string getYear() const { return extract(20,4); }string getMonth() const { return extract(4,3); }string getDay() const { return extract(8,2); }string getTime() const { return extract(11,8); }int getYear2() const { return year; }int getMonth2() const { return month; }int getDay2() const { return day; }friend int create();friend bool isTrueDate(Calendar& temp);bool isLeapYear(int year);int getTotalDay();int getStartDay();int getDaysInMonth(int a);void display();friend ostream& operator<<(ostream& out,Calendar& a);private:string extract(int offset,int count) const{string timeString=ctime(&t);return timeString.substr(offset,count);}time_t t;int year;int month;int day;};㈡主要函数详解1、总天数函数int Calendar::getTotalDay(){int i=1970,totalDay=0; //从1970年开始循环到当前年分for(;i<year;i++){if(isLeapYear(i)) //判断点前年份是否为闰年totalDay+=366; //如果是加366天,否则加365天elsetotalDay+=365;}for(i=1;i<month;i++)totalDay+=getDaysInMonth(i);return totalDay;}2、求每个月天数函数int Calendar::getDaysInMonth(int m){int a;if(m==1||m==3||m==5||m==7||m==8||m==10||m==12) //1,3,5,7,8,10,12 a=31;if(m==4||m==6||m==9||m==11) // 4,6,9,11月份a=30;if(isLeapYear(year)==true&&m==2) //闰年2月a=29;if(isLeapYear(year)==false&&m==2) //平年2月a=28;return a;}3、重载输出操作符函数ostream& operator<<(ostream& out,Calendar& a){int i=1,startDay;startDay=a.getStartDay();out<<" Sun Mon Tue Wed Thu Fri Sat"<<endl; //输出星期行for(;i<=startDay;i++)out<<" "; //前面没有日期以空格填充for(i=0;i<a.getDaysInMonth(a.convert(a.getMonth()));i++){if((i+startDay)%7==0) //每输出7个后换行out<<endl;if((i+1)==a.day){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROU ND_INTENSITY|FOREGROUND_RED); //设置字的颜色为红色out<<setw(4)<<i+1; //当月历中日期为当前日期时显示为红色SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROU ND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);}//设置字的颜色为白色,仅仅使当前日期显示为红色,其他日期为白色else{out<<setw(4)<<i+1;}}cout<<endl;return out;}4、判断输入日期是否正确函数bool isTrueDate(Calendar& temp){if(temp.day<=temp.getDaysInMonth(temp.month)) return true; //输入的天数是不是小于当月最大日期elsereturn false;if(temp.isLeapYear(temp.year)&&temp.month==2){if(temp.day<=29) //闰年2月是不是小于29天return true;elsereturn false;}if(!temp.isLeapYear(temp.year)&&temp.month==2){if(temp.day<=28) //平年2月是不是小于28天return true;elsereturn false;}}5、实时显示时钟函数int localTime(){int i=0;time_t now;struct tm *timenow;HANDLE hStdout;//定义句柄CONSOLE_SCREEN_BUFFER_INFO pBuffer;//CONSOLE_CURSOR_INFO 结构体中包含了关于命令行光标的一些信息,是否显示和光标大小两个信息。
通过更改这个结构体,再赋给命令行,就可以实现想要的一些效果了hStdout = GetStdHandle(STD_OUTPUT_HANDLE);GetConsoleScreenBufferInfo(hStdout, &pBuffer);//让句柄指向当前进程,获取当前光标位置COORD pos; //COORD结构体,与位置有关while(i<10){time(&now);//time()用来获取当前的系统时间,返回的结果是一个time_t类型,原型time_t time(time_t *t);//如果t是空指针,直接返回当前时间。
如果t不是空指针,返回当前时间的同时,将返回值赋予t指向的内存空间timenow = localtime(&now);//原型struct tm *localtime(const time_t *clock)//把从1970-1-1零点零分到当前时间系统所偏移的秒数时间转换为本地时间SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROU ND_INTENSITY|FOREGROUND_GREEN); //设置字的颜色为绿色,时钟绿色输出cout<<asctime(timenow);//函数原型char* asctime (const struct tm * timeptr),把timeptr 指向的tm结构体中储存的时间转换为字符串字符串格式返回pos.X=0;pos.Y=pBuffer.dwCursorPosition.Y;//设置光标位置为排头SetConsoleCursorPosition(hStdout,pos);//移动光标到排头i++;Sleep(1000);}SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROU ND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);//设置字的颜色为白色return 1;}6、菜单函数int select(){int n=0;cout<<"********************************"<<endl;cout<<"* 1.显示当月日历 *"<<endl;cout<<"* 2.查询日历 *"<<endl;cout<<"* 3.实时显示时钟 *"<<endl;cout<<"* 4.退出软件 *"<<endl;cout<<"********************************"<<endl;cout<<endl;cout<<"please selset the operator!"<<endl;cin>>n;cout<<n<<endl;while(n>4||n<1) //纠错{cout<<"the numble you input is wrong ,try again!"<<endl;// flushall();cin>>n;}return n;}第四章调试分析<1>程序运行测试①进入程序界面:(进入程序的第一步)②选择操作1:(可以看到显示出当月月历,并且当天用红色标出)③再次选择,选择操作2(提示是以年月方式,或者以年月日方式查询月历)(选择方式一,并输入1992年13月,提示输入错误,清再次输入)(再次输入1992年12月后得到正确结果)④再次选择操作,选择操作3(可以看到时间在不断变化,达到了实际效果)第五章用户使用说明这是一个简单的万年历程序,用户可以通过键入年月或者年月日,便可以轻松快速的查询到当月月历,还可以输入1快速的得到现在用户所处月的月历,每天的信息一目了然,方便快捷,可能够通过键入3来获取当前时间(精确到秒)。