程序设计方法作业
问题描述:中国有句俗语叫“三天打鱼两天晒网”。某人从2010年1月1日起开始“三天打鱼两天晒网”,问这个人在以后的某一天中是“打鱼”还是“晒网”。用C或C++语言/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.若输入数据中有错误的数据,如下图所示:
那么运行后会出现错误提示:
结果输出到文件中:
总结:
- 一开始我想用字符数组保存结果,如下图:
结果发现提示错误,后来将[20]去掉后发现还是提示错误。如图:
这是因为c语言中无法在非初始化的情况下对整个字符数组赋值,后来我又定义了一个指向字符数组的指针,让它指向该字符数组,并用于输出数据,如下图:
发现成功运行。这还是因为c语言的一些限制,因此要非常小心这些比较隐蔽又容易出错的地方,这样才能提高编程的效率与质量。
学习心得:
经过这次编程,我深深地明白了编程是一个日积月累地东西,只有长时间地练习才能提高自己的编程水平,实践出真知,学习中切忌只学不做,理论不与实践结合就只能是纸上谈兵。
路还很长,慢慢走。