C++记账簿

头文件

account_item.h

c 复制代码
#pragma once
#include "common.h"

struct AccountItem
{
	string itemType;
	int amount;
	string detail;
};

// 操控记账簿
void loadDataFromFile(vector<AccountItem>& items);
void accounting(vector<AccountItem>& items);
void query(const vector<AccountItem>& items);

void income(vector<AccountItem>& items);
void expand(vector<AccountItem>& items);
void insertIntoFile(const AccountItem& item);

void queryItems(const vector<AccountItem>& items);
void queryItems(const vector<AccountItem>& items, const string itemType);
void printItem(const AccountItem& item);

common.h

c 复制代码
#pragma once

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

using namespace std;

#define INCOME "收入"
#define EXPAND "支出"
#define FILENAME "D:\\AccountBook.txt"

// 显示菜单
void showMainMenu();
void showAccountingMenu();
void showQueryMenu();

// 合法性校验
char readMenuSelection(int options);
char readQuitConfirm();
int readAmount();

C++源码

account.cpp

c 复制代码
#include "common.h"
#include "account_item.h"

int main() {
	vector<AccountItem> items;
	loadDataFromFile(items);

	bool quit = false;
	while (!quit)
	{
		showMainMenu();
		char key = readMenuSelection(3);
		switch (key)
		{
		case '1':
			showAccountingMenu();
			accounting(items);
			break;
		case '2':
			showQueryMenu();
			query(items);
			break;
		case '3':
			cout << "\n确认退出? (Y/N): ";
			if (readQuitConfirm() == 'Y')
				quit = true;
			break;
		default:
			break;
		}
		cout << "\n";
	}
}
c 复制代码
#include "common.h"

void showMainMenu() {
	system("cls");
	cout << "\n";
	cout << "================== 欢迎使用记账簿 ====================" << endl;
	cout << "|                                                    |" << endl;
	cout << "|===============     1  记 账          ==============|" << endl;
	cout << "|===============     2  查 询          ==============|" << endl;
	cout << "|===============     3  退 出          ==============|" << endl;
	cout << "|____________________________________________________|" << endl;
	cout << "\n请选择(1-3):";
}

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

void showQueryMenu() {
	system("cls");
	cout << "\n";
	cout << "================== 先择查询条件 =====================" << endl;
	cout << "|                                                   |" << endl;
	cout << "|===============     1  统计所以账目  ==============|" << endl;
	cout << "|===============     2  统 计 收 入   ==============|" << endl;
	cout << "|===============     3  统 计 支 出   ==============|" << endl;
	cout << "|===============     4  返回主菜单    ==============|" << endl;
	cout << "|___________________________________________________|" << endl;
	cout << "\n请选择(1-4):";
}

operations.cpp

c 复制代码
#include "common.h"
#include "account_item.h"

// ------------------------------- 0 载入 -----------------------------------
void loadDataFromFile(vector<AccountItem>& items) {
	// 逐行读取每一条账目,包装成AccountItem
	ifstream input(FILENAME);
	AccountItem item;
	while (input >> item.itemType >> item.amount >> item.detail) {
		items.push_back(item);
	}
	input.close();
}


// ------------------------------- 1 记账 -----------------------------------
void accounting(vector<AccountItem>& items) {

	char key = readMenuSelection(3);
	switch (key)
	{
	case '1': //收入
		income(items);
		break;
	case '2': //支出
		expand(items);
		break;
	case '3': //返回主菜单
		break;
	default:
		break;
	}
	cout << "\n";
}

void income(vector<AccountItem>& items) {
	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;
	//cin.get();
	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" ;
	output << item.detail << endl;
	output.close();
}

void expand(vector<AccountItem>& items) {
	AccountItem item;
	item.itemType = EXPAND;
	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;
	//cin.get();
	string line;
	getline(cin, line);
}

// ------------------------------- 2 查询 -----------------------------------
void query(const vector<AccountItem>& items) {

	char key = readMenuSelection(4);
	switch (key)
	{
	case '1': //查询所有账目,并统计总收支
		queryItems(items);
		break;
	case '2': //查询所有收入,并统计总收入
		queryItems(items, INCOME);
		break;
	case '3': //查询所有支出,并统计总支出
		queryItems(items, EXPAND);
		break;
	case '4': //返回主菜单
		break;
	default:
		break;
	}
	cout << "\n";
}

void queryItems(const vector<AccountItem>& 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";
	cout << "总收支:" << 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;
}


void queryItems(const vector<AccountItem>& 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)
			continue;
		printItem(item);
		total += item.amount;
	}
	// 打印总收支
	cout << "==========================================================================\n";
	cout << ((itemType == INCOME) ? "总收入:" :"总支出:" )<< total << endl;
	cout << "\n请按回车建返回主菜单..." << endl;
	string line;
	getline(cin, line);
}

read_input.cpp

c 复制代码
#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;
	while (true) {
		getline(cin, str);
		if (str.size() != 1 ||( toupper(str[0]) != 'Y' && toupper(str[0]) != 'N'))
			cout << "输入错误,请重新输入(Y/N):";
		else
			break;
	}
	return toupper(str[0]);
}

int readAmount() {
	int amount;
	string str;
	while (true) {
		getline(cin, str);
		// 字符串int
		try {
			amount = stoi(str);
			break;
		}
		catch (invalid_argument e) {
			cout << "输入错误,请正确输入数字:";
		}
	}
	return amount;
}
相关推荐
萧瑟余晖2 分钟前
Spring Batch核心模型与快速上手详解
java·spring·batch
缓慢更新27 分钟前
AI 辅助生成单测:从接口定义到用例的流水线
java·服务器·前端·网络·数据库·人工智能
超级架构师38 分钟前
PRAXO-CORE 2.5.0:用 conformance 和显式边界构建 Go Agent 框架
开发语言·人工智能·后端·golang·ai编程·智能体框架·praxo-core
时间的拾荒人1 小时前
CMake 常用命令详解:从版本声明到安装部署
c++·面试
叼烟扛炮1 小时前
Linux 学习笔记(四十三):网络编程进阶——自定义协议解决 TCP 粘包与守护进程
linux·开发语言·网络·笔记·tcp/ip
LMT流氓兔2 小时前
第五单元——第十六课:给书店助手加上网页界面
java·开发语言·jvm·人工智能·oracle·langchain·1024程序员节
专注仿真2 小时前
梯度提升类(XFBoost)算法详解与代码实例
开发语言·人工智能·python·算法·大模型训练·控制算法
外收内放2 小时前
Python基础语法练习题(75)
开发语言·python·学习
starzy19903 小时前
Scala循环与判断:一切皆表达式的控制流
开发语言·人工智能·scala
wangbing11253 小时前
平台介绍-modbus设备调试
java