程序设计方法作业

问题描述:中国有句俗语叫“三天打鱼两天晒网”。某人从201011日起开始“三天打鱼两天晒网”,问这个人在以后的某一天中是“打鱼”还是“晒网”。用CC++语言/java/python实现程序解决问题。

基本要求:1.程序风格良好(使用自定义注释模板),提供友好的输入输出。

提高要求:1.输入数据的正确性验证。

2.使用文件进行数据测试。如将日期 20100101 20111214 等数据保存在in.txt文件中,程序读入in.txt文件进行判定,并将结果输出至out.txt文件。

算法思路:

要想解决这个问题,可以大致分为以下几步:

第一步:由输入的数据计算出总的间隔天数。

第二步:用总的间隔天数除于问题描述的一个周期,若余数为1,2,3,那么则这个人在打鱼,否则他在晒网。

其中最为关键的就是第一步,我的想法是先计算当年前所有年的总共天数。具体代码如下:

for (int i = 0; i < year - start_year; i++)//判断是否为闰年,若是则使标记加一。

      {

         if (start_year / 4 == 0 && start_year / 100 != 0)

            leap += 1; //标记加一。

         start_year++;

      }

      sum = sum + year - start_year + leap;//计算除当年以前所有年总共的天数。

然后再计算当年的天数并合计到总天数,具体代码如下:

if (year / 4 == 0 && year / 100 != 0)//计算当年的天数并合计总共的天数。

      {

         switch (month)

         {

         case 1:sum = sum + day; break;

         case 2:sum = sum + 31 + day; break;

         case 3:sum = sum + 29 + day; break;

         case 4:sum = sum + 31 + day; break;

         case 5:sum = sum + 30 + day; break;

         case 6:sum = sum + 31 + day; break;

         case 7:sum = sum + 30 + day; break;

         case 8:sum = sum + 31 + day; break;

         case 9:sum = sum + 31 + day; break;

         case 10:sum = sum + 30 + day; break;

         case 11:sum = sum + 31 + day; break;

         case 12:sum = sum + 30 + day; break;

         default:printf("data error!");

         }

      }

      else

      {

         switch (month)

         {

         case 1:sum = sum + day; break;

         case 2:sum = sum + 31 + day; break;

         case 3:sum = sum + 28 + day; break;

         case 4:sum = sum + 31 + day; break;

         case 5:sum = sum + 30 + day; break;

         case 6:sum = sum + 31 + day; break;

         case 7:sum = sum + 30 + day; break;

         case 8:sum = sum + 31 + day; break;

         case 9:sum = sum + 31 + day; break;

         case 10:sum = sum + 30 + day; break;

         case 11:sum = sum + 31 + day; break;

         case 12:sum = sum + 30 + day; break;

         default:printf("data error!");

         }

      }

数据的输入应题目要求进行文件的输入,这里采用C语言的fscanf()以及fprintf()函数,具体代码如下:

while (fscanf(p, "%d %d %d", &year, &month, &day) != EOF)

其中输入数据的正确性需要得到验证,具体代码如下:

if (year < 2010 || year>2019)//判断数据的正确性,错误则输出提示,停止数据输入。

      {

         printf("data error!");

         return 0;

      }

 

第一步完成后,第二步就比较简单,具体代码如下:

if (sum % 5 == 1 || sum % 5 == 2 || sum % 5 == 3)//计算得出结果打鱼还是晒网,并存储结果。

      {

         printf("这一天是%d年%d月%d日\n", year, month, day);

         printf("他在打鱼!\n");

         pt = "他在打鱼!";

      }

      else

      {

         printf("这一天是%d年%d月%d日\n", year, month, day);

         printf("他在晒网!\n");

         pt = "他在晒网!";

      }

数据的输出应题目要求进行文件的输出,这里采用C语言的fprintf()函数,具体代码如下:

 

fprintf(p1, "%-10d%10d%10d%20s\n", year, month, day, pt);//输出结果到文件中。

至此就完成了该问题的解决方法。

附具体代码如下:

#include<iostream>

using namespace std;

int main()

{

   int year, month, day, sum = 0, start_year = 2010, leap = 0;//定义年,月,日,总的天数,起始年份,leap作为是否为闰年的标记。

   char result[20];//定义一个字符数组,用于保存结果。

   char *pt = result;//定义一个指向字符数组的指针,用于输出结果。

   FILE *p;//定义文件指针。

   FILE *p1;//定义文件指针。

   if ((p = fopen("in.txt", "r")) == NULL)//打开文件

   {

      printf("无法打开文件\n");

      exit(1);

   }

   if ((p1 = fopen("out.txt", "w")) == NULL)//打开文件

   {

      printf("无法打开文件\n");

      exit(1);

   }

   while (fscanf(p, "%d %d %d", &year, &month, &day) != EOF)//读取文件中的数据并用于判断。

   {

      if (year < 2010 || year>2019)//判断数据的正确性,错误则输出提示,停止数据输入。

      {

         printf("data error!");

         return 0;

      }

      for (int i = 0; i < year - start_year; i++)//判断是否为闰年,若是则使标记加一。

      {

         if (start_year / 4 == 0 && start_year / 100 != 0)

            leap += 1;//标记加一。

         start_year++;

      }

      sum = sum + year - start_year + leap;//计算除当年以前所有年总共的天数。

      if (year / 4 == 0 && year / 100 != 0)//计算当年的天数并合计总共的天数。

      {

         switch (month)

         {

         case 1:sum = sum + day; break;

         case 2:sum = sum + 31 + day; break;

         case 3:sum = sum + 29 + day; break;

         case 4:sum = sum + 31 + day; break;

         case 5:sum = sum + 30 + day; break;

         case 6:sum = sum + 31 + day; break;

         case 7:sum = sum + 30 + day; break;

         case 8:sum = sum + 31 + day; break;

         case 9:sum = sum + 31 + day; break;

         case 10:sum = sum + 30 + day; break;

         case 11:sum = sum + 31 + day; break;

         case 12:sum = sum + 30 + day; break;

         default:printf("data error!");

         }

      }

      else

      {

         switch (month)

         {

         case 1:sum = sum + day; break;

         case 2:sum = sum + 31 + day; break;

         case 3:sum = sum + 28 + day; break;

         case 4:sum = sum + 31 + day; break;

         case 5:sum = sum + 30 + day; break;

         case 6:sum = sum + 31 + day; break;

         case 7:sum = sum + 30 + day; break;

         case 8:sum = sum + 31 + day; break;

         case 9:sum = sum + 31 + day; break;

         case 10:sum = sum + 30 + day; break;

         case 11:sum = sum + 31 + day; break;

         case 12:sum = sum + 30 + day; break;

         default:printf("data error!");

         }

      }

      if (sum % 5 == 1 || sum % 5 == 2 || sum % 5 == 3)//计算得出结果打鱼还是晒网,并存储结果。

      {

         printf("这一天是%d年%d月%d日\n", year, month, day);

         printf("他在打鱼!\n");

         pt = "他在打鱼!";

      }

      else

      {

         printf("这一天是%d年%d月%d日\n", year, month, day);

         printf("他在晒网!\n");

         pt = "他在晒网!";

      }

      fprintf(p1, "%-10d%10d%10d%20s\n", year, month, day, pt);//输出结果到文件中。

   }

   fclose(p);//关闭文件。

   fclose(p1);//关闭文件。

   return 0;

}

流程图如下:

 

程序设计方法作业

 

 

 

调试及测试截屏:

1.数据输入文件截图:

程序设计方法作业

运行程序后:

程序设计方法作业

    由图容易知道从文件中输入的数据被正确接收,在显示输入数据的同时显示了输出的结果。

2.若输入数据中有错误的数据,如下图所示:

程序设计方法作业

那么运行后会出现错误提示:
程序设计方法作业

       结果输出到文件中:
程序设计方法作业

       总结:

  1. 一开始我想用字符数组保存结果,如下图:

程序设计方法作业

       结果发现提示错误,后来将[20]去掉后发现还是提示错误。如图:

程序设计方法作业

这是因为c语言中无法在非初始化的情况下对整个字符数组赋值,后来我又定义了一个指向字符数组的指针,让它指向该字符数组,并用于输出数据,如下图:

程序设计方法作业

发现成功运行。这还是因为c语言的一些限制,因此要非常小心这些比较隐蔽又容易出错的地方,这样才能提高编程的效率与质量。

学习心得:
经过这次编程,我深深地明白了编程是一个日积月累地东西,只有长时间地练习才能提高自己的编程水平,实践出真知,学习中切忌只学不做,理论不与实践结合就只能是纸上谈兵。

路还很长,慢慢走。