三天打鱼两天晒网(c/c++)

三天打鱼两天晒网(c/c++)

问题要求:中国有句俗语叫“三天打鱼两天晒网”。某人从2010年1月1日起开始“三天打鱼两天晒网”,问这个人在以后的某一天中是“打鱼”还是“晒网”。用C/C++实现程序解决问题。
(1)提供良好的输入和输出,将输入的正确格式的日期进行判断并且保存至指定文件。(此代码仅保留最近一次查询结果)
(2)从指定xxx.txt中获取日期,并将结果输出,保存至另一个xxx1.txt中。

二、算法设计

1.题目分析
(1)单次查询,将输入的年月日进行判断,若其中的任何一项的有错误,则重新进行输入,当年月日均输入正确后,计算出距离2010年1月1日的总天数,并对5求模,得出结果并输出,将日期及结果以字符串保存至sqx.txt。
(2)文件查询,首先判断in.txt文件是否存在,若不存在则提示错误;若存在则对文件中日期进行正确性验证,若有误则输出错误,若正确则将字符串转化为整型数字进行判断求解,计算出距离2010年1月1日的总天数,并对5求模,得出结果。输出日期及相应结果,并将其保存至out.txt文件。

2.算法设计
(1)单次查询中对输入的年月日进行判断,超出年限则反复调用输入函数进行重新输入。输入正确则进行求解,并将输入的整型的日期通过string库中的to_string()函数转化为字符串。利用ofstream将文件打开,把字符串日期及结果输入至文件进行保存。
(2)文件查询首先通过ifstream打开文件,若文件不存在则报错,文件存在则将字符串日期通过string库中的substr()将日期进行切片,使用stoi()将字符串转化为整型进行判断求解。将结果通过ofstream写入文件进行保存。

三、业务流程图算法设计
在这里插入图片描述
四、主要代码

/*********************************************************************************                                      
*FileName:  Test1.cpp
*Author:  Elf.苏洛曦
*e-mail: 
*Version:  1.0.0
*Date:  2019.2.26
*Description: 中国有句俗语叫“三天打鱼两天晒网”。某人从2010年
*             1月1日起开始“三天打鱼两天晒网”,问这个人在以后
*			  的某一天中是“打鱼”还是“晒网”?
*History: 
1.Date:    2019.2.26
  Author:  Elf.苏洛曦
  Modification:   Create  project
2.Date:    2019.2.27
  Author:  Elf.苏洛曦
  Modification:   Edit  project
3.Date:    2019.2.28
  Author:  Elf.苏洛曦
  Modification:   Edit  project
**********************************************************************************/

#include<fstream>
#include<iostream>
#include<string>

using namespace std;
string date;      //文件中的日期
string line_year; //文件中的年
string line_month; //文件中的月
string line_day;   //文件中的日
int year;   //输入的年
int month;  //输入的月
int day;    //输入的天
int day1[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };    //平年每月的天数
int day2[13] = { 0,31,29,31,30,31,30,31,31,30,31,30,31 };    //闰年每月的天数
int sum;   //查询日期距离20100101的总天数

//输入查询的年份
void inputYear() {
	cout << "请输入您想查询的年份(如:2012):" << endl;
	cin >> year;
	if (year < 2010) {
		cout << "您输入的年份不在查询范围内,请重新输入!" << endl;
			inputYear();
	}
}

//判断人输入年份是平年还是闰年
int judgeYear(int year) {
	if ((year%4 == 0 && year%100 != 0) || year%400 == 0) {
		return 1;
	}
	else {
		return 0;
	}
}

//输入想要查询的月份
void inputMonth() {
	cout << "请输入您想查询的月份:" << endl;
	cin >> month;
	if (month < 1 || month > 12) {
		cout << "您输入的月份有误,请重新输入!" << endl;
		inputMonth();
	}
}

//输入想要查询的日期
void inputDay() {
	cout << "请输入您想查询的日期:" << endl;
	cin >> day;
}

//判断输入的日期是否超出该年该月的范围
void judgeDay(int year) {
	if (year == 0) {
		if (day < 0 || day > day1[month]) {
			cout << "您输入的天数不在本年该月的范围内:" << endl;
			inputDay();
		}
	}
	else {
		if (day < 0 || day > day2[month]) {
			cout << "您输入的天数不在本年该月的范围内:" << endl;
			inputDay();
		}
	}
}

//判断文件中的日期
int judgeFileDay(int year) {
	if (year == 0) {
		if (day < 0 || day > day1[month]) {
			return 0;
		}
	}
	else {
		if (day < 0 || day > day2[month]) {
			return 0;
		}
	}
}

//求距离2010年1月1日的总天数
void getSum() {
	for (int m_year = 2010; m_year < year; m_year++)
	{
		if (judgeYear(m_year) == 0) {
			sum += 365;
		}
		else {
			sum += 366;
		}
	}

	for (int i = 1 ; i < month ; i++)
	{
		judgeDay(year);
		if (year == 0) {
			sum += day1[i];
		}
		else {
			sum += day2[i];
		}
	}
	sum += day;
}

//将键入的正确日期保存至sqx.txt文件中
void setFile() {
	ofstream writefile("./sqx.txt");

	if (!writefile) {
		cerr << "打开 sqx.txt 错误!" << endl;
		exit(1);
	}
	else {
		line_year = to_string(year);
		if (month < 10) {
			line_month = "0" + to_string(month);
		}
		else {
			line_month = to_string(month);
		}
		if (day < 10) {
			line_day = "0" + to_string(day);
		}
		else {
			line_day = to_string(day);
		}

		date = line_year + line_month + line_day;
		getSum();

		if (sum % 5 > 0 && sum % 5 < 4) {
			writefile << date << '\t' << "此人这一天在打鱼" << endl;
			cout << date << '\t' << "此人这一天在打鱼" << endl;
		}
		else {
			writefile << date << '\t' << "此人这一天在晒网" << endl;
			cout << date << '\t' << "此人这一天在晒网" << endl;
		}
	}
	writefile.close();
}

//在in.txt文件中对输入的日期进行判断,并将结果输入至out.txt文件中
void compareDate() {
	ifstream infile("./in.txt");

	if (!infile) {
		cerr << "打开 in.txt 错误!" << endl;
		system("pause");
		exit(1);
	}

	ofstream outfile("./out.txt");

	if (!outfile) {
		cerr << "打开 out.txt 错误!" << endl;
		exit(1);
	}

	cout << "你所查询的文件中的日期及结果如下:" << endl;

	while (getline(infile, date)) {
		if (date.length() != 8) {
			cout << date << '\t' << "格式错误" << endl;
			outfile << date << '\t' << "格式错误" << endl;
		}
		else{

		    year = stoi(date.substr(0, 4));     //将字符串转化为整型数字,0为起始位,4为截取长度
		    month = stoi(date.substr(4, 2));
		    day = stoi(date.substr(6, 2));

		    if (year < 2010 || month < 0 || month > 12) {
			    cout << date << '\t' << "日期有错" << endl;
			    outfile << date << '\t' << "日期有错" << endl;
		}
		    else{
			    judgeYear(year);
			    if ((judgeFileDay(year)) == 0) {
				    cout << date << '\t' << "日期有错" << endl;
				    outfile << date << '\t' << "日期有错" << endl;
			    }
			    else {

				    getSum();
				    if (sum % 5 > 0 && sum % 5 < 4) {
					    outfile << date << '\t' << "这一天在打鱼" << endl;
					    cout << date << '\t' << "这一天在打鱼" << endl;
				    }
				    else {
					    outfile << date << '\t' << "这一天在晒网" << endl;
					    cout << date << '\t' << "这一天在晒网" << endl;
				    }
			    }
		    }
		}
	}
	infile.close();
	outfile.close();
}

//单次查询
void singleSearch() {
	inputYear();
	judgeYear(year);
	inputMonth();
	inputDay();
	judgeDay(year);
	setFile();
	cout << "你输入的日期正确,已保存至sqx.txt文件中" << endl;
	system("pause");
}

//文件查询
void fileSearch() {
	compareDate();
	cout << "您查询的in.txt文件中的日期,结果已保存至out.txt文件,请打开文件查看" << endl;
	system("pause");
}

//想要执行的操作
void wantSearch() {
	int number;
	cout << "问题:某人从20100101开始,三天打鱼两天晒网,查询此后某一天此人是打鱼还是晒网?" << endl;
	cout << endl;
	cout << "请输入您想进行的操作:" << endl;
	cout << "1.单次查询(查询您输入的日期,仅保存最后一次查询结果至sqx.txt)" << endl;
	cout << "2.文件查询(查询已经保存至in.txt文件的所有日期的结果,如:20101223)" << endl;
	cin >> number;

	switch (number) {
	case 1:
		singleSearch();
		break;
	case 2:
		fileSearch();
		break;
	}
}

int main(){
	wantSearch();
	}

五、调试和测试
(1)单次查询
输入错误的年月日都会提示错误,并要求重新输入,当日期输入正确后,打印日期和结果,并将其存入sqx.txt中,如下图:
在这里插入图片描述
在这里插入图片描述
(2)文件查询
当文件in.txt不存在时,提示打开错误,如下图:
在这里插入图片描述

在时,对文件中的日期进行判断,将日期及结果输出,并保存至out.txt中,如下图:
在这里插入图片描述
在这里插入图片描述
六、总结
代码实现了主要的功能,学习到了对文件的操作,但是还存在一些缺陷,在单次查询功能中仅能将最近一次的查询记录保存至文件,而且单次查询不能连续进行查询。在文件查询中,仅能对指定格式的日期(连续的数字字符串)进行判断。若文件中出现其他的符号或者字母,程序则会终止。程序还需要进行各种优化,才能使功能更加完备。

猜你喜欢

转载自blog.csdn.net/qq_42302831/article/details/88067507
今日推荐