三天打鱼两天晒网问题

三天打鱼两天晒网问题

文件名称:三天打鱼两天晒网
编程语言:C++
编译器:Visual Studio 2019
完成日期:2021年3月21日

一、问题:

中国有句俗语叫“三天打鱼两天晒网”。某人从2010年1月1日起开始“三天打鱼两天晒网”,问这个人在以后的某一天中是“打鱼”还是“晒网”。用C或C++语言实现程序解决问题。
基本要求:1.程序风格良好(使用自定义注释模板),提供友好的输入输出。
提高要求:
1.输入数据的正确性验证。
2.使用文件进行数据测试。如将日期 20100101 20111214 等数据保存在in.txt文件中,程序读入in.dat文件进行判定,并将结果输出至out.txt文件。

二、设计思路:

根据题意,本题可理解为一个与周期有关的问题,由于“打鱼晒网”一共5天。因此所求是总天数对5取余的结果,如果结果是1或2或3则是在打渔,其余就是在晒网。
故将该题分为以下两个板块:
(1)计算从2010.1.1到指定日期共有多少天(这一部分是关键部分,其中涉及到某一年与2010年间是否有闰年,平年2月28天,闰年2月29天),可按照以下方法进行计算:先算某一年的1.1到2010.1.1共多少天,再计算某一年的某月某日到这一年的1.1共多少天,再将这两个结果相加即为总天数。
(2)计算总天数对5取余的结果,余数为1,2,3是在打渔,其余是在晒网。

三、概要设计

  1. 流程图:
    在这里插入图片描述

  2. 主要设计:
    共设计4个函数:判断输入数据是否合法的shuru()函数;计算指定日期到2010.1.1总天数的sum()函数;在in.txt文件中读取数据在in.dat文件进行判定,并将结果输出至out.txt文件的file()函数;以及主函数main()函数,在其中调用file(),并实现一些输入输出。

首先第一步是判断输入的数据是否合法,从三个方面判断:(1)年份是否大于2010年;(2)月份是否大于一月小于十二月;(3)日期中的日数是否小于对应月份的总天数

if (year<2010 || (month < 1 || month>12) || (month == 2 && (year % 4 != 0 || year % 400 != 0) && day >= 29) || day>Y[month]) {
  cout << "输入错误,请重新输入!" << endl;
  exit(-1);

第二步是主要步骤,即计算从2010.1.1到指定日期共有多少天。分为三个部分计算,第一部分是计算某一年的1.1到2010.1.1的总天数;第二部分是计算指定日期到这一年的一月一日共多少天;总天数即将这两部分相加。
第一部分需要考虑的问题是某一年与2010年间是否有闰年,有多少个闰年。

for (t; t < year; t++) {
  if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)   //判定year为闰年还是平年,x=1为闰年,0为平年 
  {
   x = 1;
   d1 += 366;
  }
  else
  {
   x = 0;
   d1 += 365;
  }
 }

年份的天数计算完了,现在开始计算此年中指定日期到1.1的天数。需要考虑的是,这一年是否为闰年,以及指定的月份是否大于2月。
需要定义一个数组来存储一年中十二个月每个月对应的总天数:

int Y[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };

第二部分天数计算:

if ((year % 400 == 0)|| ((year % 4 == 0)&&(year % 100 != 0)))   //判断这一年是否为闰年,m=1表示这一年是闰年,m=0表示不是
  m = 1;
 else
  m = 0;
 for (int u = 1; u < month; u++)
  d2 += Y[month];
 if ((m = 1) && (month > 2))
  d2 = d2 + day + 1;
 else
  d2 = d2 + day;

d1,d2都算好后,现在可以得到总天数:

d3 = d1 + d2;

第三步就是有关文件的操作了,需要用到ofstream类和ifstream类,通过文件流对象进行操作。通过键盘将年月日日期输入保存到in.txt文件里,然后通过文件流对象的操作,读取in.txt里的内容并放到in.dat文件里进行数据的判定,读取出来后进行操作,调用一二步的两个函数,在读取日期数据后分别进行数据合法性的判断以及总天数的计算 以及判断是在打渔还是晒网,通过总天数对5取余的结果,余数为1、2、3是在打渔,其余是在晒网,最后将结果输出到out.txt文件里。

 ifstream f1;
 ofstream f2;
 ofstream f3;
 f1.open("C:\\Users\\wang\\in.txt");
 f2.open("C:\\Users\\wang\\in.dat");
 f3.open("C:\\Users\\wang\\out.txt");
 f1 >> year;    //将年月日数据保存在in.txt
 f1 >> month;
 f1 >> day;
 //在in.dat中进行数据的判定
    if (year<2010 || (month < 1 || month>12) || (month == 2 && (year % 4 != 0 || year % 400 != 0) && day >= 29) || day>Y[month])
  f2 << "输入数据错误";
    else {
 f2 << year << "年";
 f2 << month << "月";
 f2 << day << "日";
     }
 shuru(year, month, day);
 sum(year, month, day);
 if (year == 0 || month == 0 || day == 0) //读取数据不合适则结束读取
 {
  exit(-1);
 }
 cout << year << "年" << month << "月" << day << "日" << endl;  //输出从文件中读取的结果
 cout << "这一天与2020.1.1相差" << d3 - 1 << "天";      //输出相差的总天数
 if ((s == 1) || (s == 2) || (s == 3))  //通过对5取余的结果判断是打渔还是晒网,结果为1或2或3时是打渔,其他是晒网
 {
  f3 << year << "年" << month << "月" << day << "日" << " " << "这一天在打渔" << endl;
 }
 else
 {
  f3 << year << "年" << month << "月" << day << "日" << " " << "这一天在晒网" << endl;
 }
 f3.close();    //关闭f3文件

以上都完成后,就是关于main()函数的操作了,在main()中调用定义的文件操作函数,并提供一些输出语句:

int main() {
 file();
 cout << endl;
 if (s > 0 && s < 4)
  cout << "这一天在打渔" << endl;
 else
  cout << "这一天在晒网" << endl;
}

四、结果展示

  1. 输入一个正确日期
    在in.txt中输入数据,in.dat中进行判定:
    在这里插入图片描述在这里插入图片描述
    在out.txt中读取结果以及结果显示在这里插入图片描述
    在这里插入图片描述
  2. 输入一个错误日期
    在in.txt中输入数据,in.dat中进行判定:
    在这里插入图片描述
    在这里插入图片描述
    在out.txt中读取结果以及结果显示,此时out.txt中不会显示数据
    在这里插入图片描述在这里插入图片描述

五、总结

本人认为此次总体设计还算良好,但有些方面仍需要完善。比如可以设计一个类,包括year、month、day等成员变量,以及判断、计算天数、文件操作等成员函数,最后通过类去构造对象调用函数,进行操作。如有错误也欢迎大家进行指正。
最后附上本程序的完整代码:

#include <iostream>
#include<string>
#include<fstream>
using namespace std;
int year, month, day, x, m, i;
int Y[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
int d1 = 0;
int d2 = 0;
int d3;
int s = d3 % 5;
int t = 2010;
void shuru(int year, int month, int day) {
 //前提:输入数据必须正确
 if (year<2010 || (month < 1 || month>12) || (month == 2 && (year % 4 != 0 || year % 400 != 0) && day >= 29) || day>Y[month]) {
  cout << "输入错误,请重新输入!" << endl;
  exit(-1);
 }
}
void sum(int year, int month, int day) {
 //判断某一年与2010年之间是否有闰年  并计算从2010年1月1日到某一年的1月1日共多少天
 for (t; t < year; t++) {
  if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) //判定year为闰年还是平年,x=1为闰年,0为平年
  {
   x = 1;
   d1 += 366;
  }
  else
  {
   x = 0;
   d1 += 365;
  }
 }
 //计算某年中的某月某日到1月1日共多少天
 if  ((year % 400 == 0)|| ((year % 4 == 0)&&(year % 100 != 0)))   //判断这一年是否为闰年,m=1表示这一年是闰年,m=0表示不是
  m = 1;
 else
  m = 0;
 for (int u = 1; u < month; u++)
  d2 += Y[month];
 if ((m = 1) && (month > 2))
  d2 = d2 + day + 1;
 else
  d2 = d2 + day;
 d3 = d1 + d2;
}
void file() {
 ifstream f1;
 ofstream f2;
 ofstream f3;
 f1.open("C:\\Users\\wang\\in.txt");
 f2.open("C:\\Users\\wang\\in.dat");
 f3.open("C:\\Users\\wang\\out.txt");
 f1 >> year;    //将年月日数据保存在in.txt
 f1 >> month;
 f1 >> day;
 //在in.dat中进行数据的判定
    if (year<2010 || (month < 1 || month>12) || (month == 2 && (year % 4 != 0 || year % 400 != 0) && day >= 29) || day>Y[month])
  f2 << "输入数据错误";
    else {
 f2 << year << "年";
 f2 << month << "月";
 f2 << day << "日";
     }
 shuru(year, month, day);
 sum(year, month, day);
 if (year == 0 || month == 0 || day == 0) //读取数据不合适则结束读取
 {
  exit(-1);
 }
 cout << year << "年" << month << "月" << day << "日" << endl;  //输出从文件中读取的结果
 cout << "这一天与2020.1.1相差" << d3 - 1 << "天";      //输出相差的总天数
 if ((s == 1) || (s == 2) || (s == 3))  //通过对5取余的结果判断是打渔还是晒网,结果为1或2或3时是打渔,其他是晒网
 {
  f3 << year << "年" << month << "月" << day << "日" << " " << "这一天在打渔" << endl;
 }
 else
 {
  f3 << year << "年" << month << "月" << day << "日" << " " << "这一天在晒网" << endl;
 }
 f3.close();    //关闭f3文件
}
int main() {
 file();
 cout << endl;
 if (s > 0 && s < 4)
  cout << "这一天在打渔" << endl;
 else
  cout << "这一天在晒网" << endl;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值