49. 海豚记账簿软件(b站的一个小项目)

闲着也是闲着就跟着别人做了一个小项目

目录

1.需求和目标

2.整体功能描述

3.核心思路

4.全部代码


1.需求和目标

项目的需求,实现一个叫做“海豚记账簿”的基于命令行界面的家庭记账软件。

 

2.整体功能描述

这个软件相对简单,只需要基于命令行做纯文本的交互,不涉及图形化界面。作为一个记账软件,主要有两大功能:记账和查询。也就是说,软件需要能够记录家庭中每一笔收入、支出的账目,并提供查询收支明细的功能。而且为了让软件有真正的实用价值,需要对数据做持久化保存;我们这里只需要存放在一个指定的文本文件中。

项目采用分级菜单方式,每一级菜单应该有“返回主菜单”功能;主菜单有“退出”选项。

49. 海豚记账簿软件(b站的一个小项目)_第1张图片 

 49. 海豚记账簿软件(b站的一个小项目)_第2张图片

49. 海豚记账簿软件(b站的一个小项目)_第3张图片 

3.核心思路

记账软件处理的数据,就是收入或者支出的“账目”。每一条账目数据,都应该包含收支类型、金额、备注三部分,这可以构建一个结构体类型 AccountItem 来表示。

而程序运行的开始,应该读取保存在文件中的数据,读取之后应该是一个 AccountItem 类型的数组。

在流程控制方面,如果用户不选择退出,程序就不会结束,所以应该用一个while循环来处理整个流程;当用户确认退出时,更改一个标志位,用来退出循环。

每一级菜单做键盘选择后,可以用 switch 分支语句来处理;不同的功能模块,可以包装成函数。

4.全部代码

 account_item.h

#pragma once
#include "common.h"

//定义结构体类型
struct AccountItem {
	string itemType;
	int amount;
	string detail;//备注信息
};

//针对账目数据进行操作的函数声明

//加载账目数据
void loadDataFromFile(vector& items);

//记账
void accounting(vector& items);
void insertIntoFile(const AccountItem& item);
void income(vector& items);
void outcome(vector& items);

//查询
void query(const vector& items);
void queryItems(const vector& items);
void queryItems(const vector& items, const string itemType);
void printItem(const AccountItem& item);

common.h

#pragma once
#include 
#include 
#include 
#include 

#define INCOME "收入"
#define OUTCOME "支出"
#define FILENAME "D:\\C++project\\AccountBook.txt"

using namespace std;

//通用功能性函数声明
//绘制菜单的函数
void showMainMenu(); 
void showAccountMenu();
void showQueryMenu();

//读取键盘输入进行合法性校验的函数
char readMenuSelection(int options);
char readQuitConfirm();
int readAmount();

haitunaccount.cpp

#include "account_item.h"
#include "common.h"

int main() {
	//1.加载文件中的账目数据
	vector items;
	loadDataFromFile(items);

	bool quit = false;
	while (!quit) {
		//2.显示主菜单
		showMainMenu();

		//3.读取键盘选择,并作合法性校验
		char key=readMenuSelection(3);

		switch (key) {
		case '1':    //1.记账
			showAccountMenu();  //显示记账菜单
			accounting(items);
			break;
		case '2':    //2.查询
			showQueryMenu();  //显示查询菜单
			query(items);
			break;
		case '3':    //3.退出
			cout << "\n确认退出?(Y/N):";
			if (readQuitConfirm() == 'Y')
				quit = true;
			break;
		default:
			break;
		}

		cout << endl;
	}
}

 

opperations.cpp

#include "account_item.h"
#include "common.h"


//
void loadDataFromFile(vector& items) {
	ifstream input(FILENAME);

	//逐行读取每一条账目,包装成AccountItem
	AccountItem item;
	while (input >>item.itemType>>item.amount>>item.detail) {
		items.push_back(item);
	}

	input.close();
}

//-------------------------1.记账------------------------
//记账操作
void accounting(vector& items) {
	

	//读取键盘选择,并作合法性校验
	char key = readMenuSelection(3);

	switch (key) {
	case '1':    //1.收入
		income(items);
		break;
	case '2':    //2.支出
		outcome(items);
		break;
	case '3':    //3.返回主菜单
		break;
	default:
		break;
	}
}

//记录一笔输入
void income(vector& items) {
	//新构建一个AccountItem对象
	AccountItem item;

	//类型已经确定,就是收入
	item.itemType = INCOME;

	//与用户交互,键盘输入金额和备注信息
	cout << "\n本次收入金额:";
	item.amount = readAmount();

	cout << "\n备注:";
	getline(cin, item.detail);

	//添加到vector中
	items.push_back(item);
	//写入文件做持久化保存
	insertIntoFile(item);

	//显示成功信息
	cout << "\n-------------------------------记账成功-------------------------------\n" << endl;
	cout << "\n请按回车键返回主菜单..." << endl;

	string line;
	getline(cin, line);
}

//记录一笔支出
void outcome(vector& items) {
	//新构建一个AccountItem对象
	AccountItem item;

	//类型已经确定,就是支出
	item.itemType = OUTCOME;

	//与用户交互,键盘输入金额和备注信息
	cout << "\n本次支出金额:";
	item.amount = -readAmount();

	cout << "\n备注:";
	getline(cin, item.detail);

	//添加到vector中
	items.push_back(item);
	//写入文件做持久化保存
	insertIntoFile(item);

	//显示成功信息
	cout << "\n-------------------------------记账成功-------------------------------\n" << endl;
	cout << "\n请按回车键返回主菜单..." << endl;

	string line;
	getline(cin, line);
}

//将一条账目写入文件中
void insertIntoFile(const AccountItem& item) {
	//创建一个ofstream对象,以追加方式进行写入
	ofstream output(FILENAME, ios::out | ios::app);

	output << item.itemType << "\t" << item.amount << "\t" << item.detail << endl;

	output.close();
}

//------------------------2.查询----------------------------
void query(const vector& items) {

	//读取键盘选择,并作合法性校验
	char key = readMenuSelection(4);

	switch (key) {
	case '1':    //1.查询所有账目,并统计总收支
		queryItems(items);
		break;
	case '2':    //2.查询收入,统计总收入
		queryItems(items,INCOME);
		break;
	case '3':    //3.查询支出,统计总支出
		queryItems(items, OUTCOME);
		break;
	default:
		break;
	}
}

//查询账目功能函数
void queryItems(const vector& items) {
	cout << "---------------------查询结果-----------------------" << endl;
	cout << "\n类型\t\t金额\t\t备注\n" << endl;

	//遍历所有账目,统计总收支
	int total = 0;
	for (auto item : items) {
		printItem(item);
		total += item.amount;
	}

	//输出信息
	cout << "======================================================\n" << endl;
	cout << "总收支:" << total << endl;
	cout << "\n请按回车键返回主菜单..." << endl;

	string line;
	getline(cin, line);
}

//函数重载
void queryItems(const vector& items,const string itemType) {
	cout << "---------------------查询结果-----------------------" << endl;
	cout << "\n类型\t\t金额\t\t备注\n" << endl;

	//遍历所有账目,统计总收支
	int total = 0;
	for (auto item : items) {
		if (item.itemType == itemType) {
			printItem(item);
			total += item.amount;
		}
	}

	//输出信息
	cout << "======================================================\n" << endl;
	// 使用条件运算符输出不同的字符串,根据 itemType 的值来判断
	cout << ((itemType == INCOME) ? "总收入:" : "总支出:") << total << endl;
	cout << "\n请按回车键返回主菜单..." << endl;

	string line;
	getline(cin, line);
}

//打印输出一条账目信息
void printItem(const AccountItem& item) {
	cout << item.itemType << "\t\t" << item.amount << "\t\t" << item.detail << endl;
}

 

read_input.cpp

#include "common.h"

//读取键盘输入的选项,进行合法性校验
char readMenuSelection(int options) {
	string str;

	while (true) {
		getline(cin, str);

		//进行合法性校验
		if (str.size() != 1 || str[0] - '0' <= 0 || str[0] - '0' > options) {
			cout << "输入错误,请重新选择:";
		}
		else
			break;
	}

	//输入合法
	return str[0];
}


//读取确认推出信息,并进行合法性校验
char readQuitConfirm() {
	string str;
	char ch;

	while (true) {
		getline(cin, str);

		ch = toupper(str[0]);
		//进行合法性校验
		if (str.size() != 1 || ch!='Y'&&ch!='N') {
			cout << "\n输入错误,请重新输入(Y/N):";
		}
		else
			break;
	}

	//输入合法
	return ch;
}

//读取键盘输入的金额数,并作合法性校验
int readAmount() {
	int amount;

	string str;
	while (true) {
		getline(cin, str);

		//进行合法性校验
		try {
			amount = stoi(str);//标准库函数,将str转换为int类型数据
			break;
		}
		catch (invalid_argument error) {
			cout << "输入错误,请正确输入数字:";
		}
	}

	//输入合法
	return amount;
}

 

menu.cpp

#include "common.h"
//绘制菜单的函数
void showMainMenu() {
	system("cls");    // 调用system函数,清屏,对windows有效

	cout << "--------------------------------------------------------" << endl;
	cout << "|================ 欢迎使用海豚记账簿 ==================|" << endl;
	cout << "|                                                      |" << endl;
	cout << "|****************     1 记  账     ********************|" << endl;
	cout << "|****************     2 查  询     ********************|" << endl;
	cout << "|****************     3 退  出     ********************|" << endl;
	cout << "|______________________________________________________|" << endl;

	cout << "\n请选择(1 - 3):";
}
void showAccountMenu()
{
	cout << "-------------------------------------------------------" << endl;
	cout << "|===============   选择记账种类   ====================|" << endl;
	cout << "|                                                     |" << endl;
	cout << "|***************    1 收  入      ********************|" << endl;
	cout << "|***************    2 支  出      ********************|" << endl;
	cout << "|***************    3 返回主菜单  ********************|" << endl;
	cout << "|_____________________________________________________|" << endl;

	cout << "\n请选择(1 - 3):";
}

void showQueryMenu()
{
	cout << "-------------------------------------------------------" << endl;
	cout << "|===============   选择查询条件   =====================|" << endl;
	cout << "|                                                     |" << endl;
	cout << "|***************  1 统计所有账目  *********************|" << endl;
	cout << "|***************  2 统 计 收 入   *********************|" << endl;
	cout << "|***************  3 统 计 支 出   *********************|" << endl;
	cout << "|***************  4 返回主菜单    *********************|" << endl;
	cout << "|_____________________________________________________|" << endl;

	cout << "\n请选择(1 - 4):";
}

 

你可能感兴趣的:(c++,visual,studio)