C++新闻信息管理系统.docx
《C++新闻信息管理系统.docx》由会员分享,可在线阅读,更多相关《C++新闻信息管理系统.docx(43页珍藏版)》请在冰豆网上搜索。
![C++新闻信息管理系统.docx](https://file1.bdocx.com/fileroot1/2023-4/24/19acffe3-7e90-48c1-855b-5d99432e667a/19acffe3-7e90-48c1-855b-5d99432e667a1.gif)
C++新闻信息管理系统
C++新闻信息管理系统报告
2015年3月6日
一课程设计题目与要求包括题目与系统功能要求
已知一个日期类Date,其数据成员如下classDate{private:
intm_year,m_month,m_day;//分别代表一个日期中的年月日intm_totalDaysYear;//年份m_year中的总天数};1.在此基础上,请完善以下成员函数声明和定义,要求声明为public访问标识,且成员函数在类外定义:
1)默认的构造函数,要求具有三个默认值分别为2001(年),1(月)和1(日)的形式参数,并在此构造函数内部根据m_year的值,计算总天数。
2)重载赋值操作符。
3)析构函数。
4)增加并实现以下类Date的成员函数,其功能和声明如下intgetDaysofYear();//返回一个日期在当年中的天数,如2014/2/12返回43;intgetRemainingDaysofYear();//返回一个日期在当年中的余下的天数,如2014/1/12返回353;intcompare(constDate&date);//比较date和当前对象的大小,分别返回1,0和-1代表当前对象的日期大于,等于或小于date;intoperator-(constDate&date);//计算并返回date和当前调用对象相差的天数;Dateoperator+(intdays);//计算当前对象加上days天数的日期,并返回结果
5)定义并实现一个类Date的友元函数,声明和功能如下friendostream&operator<<(ostream&out,constDate&date);//按照年/月/日格式输出,如2014/1/126);定义一个内联函数,其函数名和形式参数如下:
isLeapYear(intyear),要求返回值为布尔类型,其功能为判断year是否是闰年,闰年返回true,非闰年返回false。
2.在上题提基础上,设计一个新闻类,要求能够记录新闻发生的日期、编号(整数从1开始)、新闻类型、新闻标题、发生的地点以及新闻的内容。
该类的部分数据成员声明如下:
classNews{private:
stringm_news;//存储新闻内容,假设单词间以空格隔开,无换行符和Tab符,Datem_date;//新闻报道的时间public:
};
实现功能:
1)实现每条新闻自动编号,编号从1开始;
2)某类型新闻在某段时间内发生的次数;如2013年1月1日到2013年12月31日期间体育类的新闻数目。
3)根据特定关键词搜索相关的新闻,并将其输出到屏幕,如anti-corruption
4)统计每条新闻的英文单词数目
5)可增加和删除新闻,增加或删除的结果保存到本地文件中
6)在某日期之后一段时间内报道的新闻,并将其输出到屏幕,如在2013/1/14的169天内报道的新闻要求:
完善类的设计,实现相应功能,请加以说明你的设计。
数据成员以m_开头,如m_news,函数成员请用有意义的英文单词如上题getRemainingDaysofYear()。
假定新闻类型如下:
enumNewsType{Education,Politic,Sport,Science,Weather};每条新闻按以下格式存储在本地文本文件中,
ID:
123Date:
2014/1/13Type:
SportTitle:
AustralianOpen2014:
RogerFederer'cangetbacktohisbest'Address:
AustralianContent:
StefanEdbergbelieveshecanhelpgetRogerFedererbacktohisbest.TheSwedishsix-timeGrandSlamwinnerwillbeapartofFederer'scoachingteamfor10weeksin2014,startingwiththeAustralianOpen.SwissFederer,32,wonthelastofhis17GrandSlamsatWimbledonin2012.
二需求分析,包括问题描述、系统环境、运行要求等
1.问题描述
本题中要求书写两个类,一个类为时间类,一个是新闻类。
在时间类中,有各种处理时间的函数和重载的函数,如:
求一个日期在当年中所占的天数及剩余天数,重载输入和输出运算符,重载加减运算符等。
而新闻类则是本题的重点,中间就要实现新闻管理的所有功能。
新闻的自动编号、计算相同新闻类型发生的次数、根据关键词搜索新闻、统计新闻字数、增删新闻、输出某日期后面一段时间的新闻等等。
2.系统环境及运行要求
操作系统:
Windows8
开发环境:
MicrosoftVisualStudio2013
三概要设计,包括系统流程设计、系统模块设计等
1.系统流程设计
2.系统模块设计
时间类:
新闻类:
管理类:
四详细设计,包括类的函数成员和数据成员设计、界面设计(见问题提示)、及其它模块设计与实现
1.时间类(Date):
大纲:
数据成员:
年、月、日m_year;m_month;m_day。
函数成员:
重载函数、基本函数、功能函数、接口函数。
重载函数:
加号“+”的重载、减号“-”的重载、输入“>>”的重载、输出“<<”的重载。
基本函数:
默认构造函数、析构函数。
功能函数:
计算当前日期在本年中的天数、计算当前日期在本年中还剩余的天数、计算当前日期加上输入天数后日期、比较两日期的大小、判断当前年份是否为瑞年。
实现:
1.加减函数的重载
这是一个类对象和内置对象的加减,不同于内置类型的加减,所以需要重载。
首先,两个对象的加减不能改变时间Date类对象其本身的值,所以,在Date对象作形参时,参数的传递过程中需要形参必须为const引用类型;对于最后的返回值类型,则根据具体的情况和需要而设定。
对于“+”的重载时,我采用数组的方法,首先设定每个月具体的天数,然后在用m_day+days>m[m_month-1]是否成立来判断,除了第一次成功是days=days-(m[month-1]-m_day)-1外;后面的都是days-=m[m_month-1];days=1;这样就可以实现实现对days的减小;具体的内容就不在这儿详述了;而对于“-”,我则是使用了判断的形式,具体不详述。
2.输入输出的重载
在题目的要求中,这两个重载函数都是必须声明为友元函数,所以严格意义上来讲这两个函数是不属于Date类的成员的函数;输入输出都有两个形参,一个是功能对象,一个是待处理对象(Date);Date类对象都必须是引用类型,而在输出函数中更必须是const引用,返回值则是另外定义的那个形参。
3.基本函数
默认构造函数:
即程序员自己编写一个构造函数,给每个数据成员附上初始值
析构函数:
自己给出,便于了解编译器的内在运行。
4.功能函数:
getDayssofYear();//返回一个日期在当年中的天数。
这一个函数的设计
本来是十分简单的,先使用一个数据,在其中写入每个月的天数,在二月份加入一
个判断就行,然后用一个for(inti=1;i起来;最后加上m_day的值结束;而我却使用了if判断嵌套循环;考虑的情况十分
多不说,好容易出错。
getRemainingDaysofYear();//返回一个日期在当年中的余下
的天数;这一个函数使用365-getDayssofYear()即可;日期的大小比较使用if条件判
断即可;inlineboolisleapYear();//内联函数,判断year是否为闰年;因为这里必
须是内联函数,所以判断必须简单,不能有嵌套的判断语句出现,所以只能使用条
件语句:
m_year%4==0&&m_year%100!
=0||m_year%400==0?
1。
2.新闻类(News):
大纲:
数据成员:
m_date;m_order;m_type;m_content;m_place;m_title;
函数成员:
接口函数;默认构造函数;重载复制运算函数。
实现:
接口函数返回数据成员的应用。
默认构造函数赋给数据成员初始值。
重载“=”函数;使用const引用;返回this指针。
3.管理类(Management):
大纲:
数据成员:
vectorstu;
函数成员:
各种功能函数。
实现:
1.voidinput();//从文本中读入数据并输出到屏幕;由于我是用的是中文文本;所以输
入较为简单;每遇见一次空格就是一种数据成员输入完毕,接着是下一种类型。
注意
刚开始要有一个判断,那便是是否成功打开文件。
2.voidshow();//将信息显示在屏幕上;使用一个for循环就可以完成输出工作。
这里
面我们需要考虑的是是输出文本中的内容还是vector容器中的内容;输出文本中的内
容这个函数只能使用一次,而输出vector中的内容则可以多次。
所以,我采用了第二
种。
3.voididentifier();//对新闻进行编号;使用一个for循环就可以实现对新闻的编号;
编号后将其可入一个新建的文本文件,然后使用show()函数对其结果输出展示。
4.voidstore();//对新闻进行特定格式的储存;此函数用于使新闻在文本文件中的储存
格式与题目要求的一致。
voidlookUp();//计算某段时间内某种类型新闻发生的次数;先输入新闻类型和时间
段;然后使用for循环查找这一类型的新闻,找到后放在一个新的vector容器中;然
后在这个新的容器中找到满足条件的新闻,计数。
5.后面的各种功能函数情况比较复杂,就不具体说明。
五测试,包括对各功能模块的测试
1.菜单显示:
2.自动编号且按规定格输出并储存
3.输出某种新闻在某段时间内发生的次数
继续查找:
4.根据特定的关键词搜索新闻
5.统计每条新闻的字数
继续统计:
6.增加或删减新闻
(1)增加新闻:
输入后:
(2)删除新闻:
删除前如上图:
删除查找:
删除后:
再次删除新输入的新闻:
7.输出某日期后一段日期报道的新闻
第一次查找:
第二次查找:
8.计算两个日期相差的时间
瑞年同一年份:
平年同一年份:
不同年份:
9.某个日期加上输入天数后的日期
瑞年:
平年:
计算结果跨年分的:
10.比较两日期的大小
同一年份的:
同一天的:
不同年份的:
六结论,对系统开发的总结,设计的亮点,存在的不足,需要改进的地方
系统的开发涉及到各种类和函数的关联,虽然本次作业的要求较为简单,但作为初学者,我还是不那么得心应手。
设计的亮点:
1.按照要求,此次的新闻管理系统我们至少要写两个类,一个时间Date类,一个时间News类。
新闻是一个整体,想要管理新闻新闻的话是需要一整则新闻进行,所以,在News类中书写管理的功能函数会使得过程十分的棘手,所以,我就采用第三个类,管理类Management;在定义一个容器vector使得操作大大的简化。
2.在对新闻按照要求格式进行输出并储存到文本文件中时,在每个数据成员前面都会加上说明符;如date:
2012/2/2;ID:
15等等,像这样的格式无论是输出到文本还是屏幕都只能使用string类的对象类操作。
在后面的功能函数中我们又必须将其转化为数字,然后才能进行各种运算,这样会很麻烦。
所以我在开始的时候就将其分开,不让他们成为一个整体,这样将不会在后面进行转换,具体过程见源代码。
3.再设计show()函数时,这里我们需要考虑的是是输出文本中的内容还是vector容器中的内容。
输出文本中的内容这个函数只能使用一次,而输出vector中的内容则可以多次。
所以,我采用了第二种。
存在的不足:
作为一个新手,我对于代码的驾驭能力还是不够,不能灵活应用。
比如对于应用和指针的应用,对于循环的应用。
在这里面,最需要说的对于循环的应用,当然,简单的循环我还是会,但遇到复杂的循环就存在各种问题。
如,在对加减法进行重载的时候,刚开始,我没有想到使用数组后循环加判断,这样问题就十分的简单,但我却只使用if条件判断,造成过程超级繁琐,过程超级麻烦,代码十分冗长。
后来,我修改了加法的重载,但减法还是没有修改。
对于数组的应用也存在不熟练的问题,比如getDayssofYear();//返回一个日期在当年中的天数。
这一个函数的设计本来是十分简单的,先使用一个数据,在其中写入每个月的天数,在二月份加入一个判断就行,然后用一个for(inti=1;i对于关键词查找,我也是一带而过,不知应该怎么办。
如果使用find()函数查找的话,这样就不叫关键词查找了,而如果要提前写好关键词的话,这样工作量也就太大了吧,而且还要考虑各种相近的近义词等等。
所以对于这个我也是存在一定问题的。
七附录
程序源代码,关键代码要做注释
***********************mian函数************************
#include"management.h"
intmain(){
cout<<"*******************************************************************************"<cout<<"***************************欢迎进入新闻信息管理系统****************************"<cout<<"*******************************************************************************"<inti=0;Managementm;Daten;
m.input();m.identifier();
while(i!
=10){
cout<<'\n'<<"请输入你想要进行的功能前所对应的数字"<cout<<"1:
对已实现自动编号且自动按照要求格式储存的新闻输出"<cout<<"2:
输出某类型新闻在某段时间内发生的次数"<cout<<"3:
根据特定的关键词搜索新闻"<cout<<"4:
统计每条新闻的字数"<cout<<"5:
增加或删减新闻"<cout<<"6:
输出某日期后一段日期报道的新闻"<cout<<"7:
计算两个日期相差的时间"<cout<<"8:
某个日期加上输入天数后的日期"<cout<<"9:
比较两日期的大小"<cout<<"10:
结束"<cin>>i;
if(i<1||i>10)
cout<<"你输入的指令是错误的,请重新选选择并输入"<switch(i){
case1:
m.show();break;
case2:
m.lookUp();break;
case3:
m.find();break;
case4:
m.statistics();break;
case5:
m.change();break;
case6:
m.play();break;
case7:
n.decrease();break;
case8:
n.increase();break;
case9:
n.contrast();break;
case10:
break;
}
}
system("pause");
return0;
}
**********************Date类头文件*********************
#ifndefDATE_H
#defineDATE_H
#include
#include
usingnamespacestd;
classDate{
private:
intm_year,m_month,m_day;
intm_totalDaysYear;
public:
Date(intd=1,intm=1,inty=2001);//默认构造函数
Date&operator=(constDate&d);//重载赋值运算符
~Date();//析构函数
intgetDayssofYear();//返回一个日期在当年中的天数
intgetRemainingDaysofYear();//返回一个日期在当年中的余下的天数
intcompare(constDate&date);//比较date和当前对象的大小;返回1,0,-1,代表大于,等于,小于。
intoperator-(constDate&date);//计算并返回date和当前调用对象相差的天数
Dateoperator+(intdays);//计算并返回当前对象加上days天数的日期
friendostream&operator<<(ostream&out,constDate&date);//按照年/月/日的格式输出
friendistream&operator>>(istream&is,Date&date);
inlineboolisleapYear();//内联函数,判断year是否为闰年
int&getYear();
int&getMonth();
int&getDay();
int&getTotalDaysYear();
booloperator>=(constDate&date);
booloperator<=(constDate&date);
voidincrease();//调用“+”函数
voiddecrease();//调用“-”函数
voidcontrast();//调用compare()函数
};
#endif
**********************Date类源文件*********************
#include"date.h"
inta=1,b=0,c=-1;
inty=-1;
int&Date:
:
getYear(){
returnm_year;
}
int&Date:
:
getMonth(){
returnm_month;
}
int&Date:
:
getDay(){
returnm_day;
}
int&Date:
:
getTotalDaysYear(){
returnm_totalDaysYear;
}
Date:
:
Date(intd,intm,inty){
m_day=d;m_month=m;m_year=y;
}
Date:
:
~Date(){}
Date&Date:
:
operator=(constDate&d){
m_day=d.m_day;m_month=d.m_month;m_year=d.m_year;
return*this;
}
intDate:
:
getDayssofYear(){
if(m_month>2){
if(m_month<8){
if(m_month==3)
y=30*2+m_day;
if(3y=(m_month-1)*30+1+m_day;
if(7<=m_month)
y=(m_month-1)*30+2+m_day;
}
else{
if(m_month==8)
y=30*7+3+m_day;
if(8y=(m_month-1)*30+4+m_day;
if(m_month>10)
y=(m_month-1)*30+5+m_day;
}
if(!
isleapYear()){
y--;
}
}
else{
y=(m_month-1)*31+m_day;
}
returny;
}
intDate:
:
getRemainingDaysofYear(){
inta=getDayssofYear();
if(isleapYear()){
y=366-a;
}
elsey=365-getDayssofYear();
returny;
}
intDate:
:
compare(constDate&date){
Dated=date;
if(getYear()!
=d.getYear()){
if(getYear()>d.getYear())
returna;
if(getYear()returnc;
}
else{
intm=getDayssofYear(),n=d.getDayssofYear();
if(m>n)
returna;
if(m==n)
returnb;
if(mreturnc;
}
}
intDate:
:
operator-(constDate&