闲着也是闲着就跟着别人做了一个小项目
目录
1.需求和目标
2.整体功能描述
3.核心思路
4.全部代码
项目的需求,实现一个叫做“海豚记账簿”的基于命令行界面的家庭记账软件。
这个软件相对简单,只需要基于命令行做纯文本的交互,不涉及图形化界面。作为一个记账软件,主要有两大功能:记账和查询。也就是说,软件需要能够记录家庭中每一笔收入、支出的账目,并提供查询收支明细的功能。而且为了让软件有真正的实用价值,需要对数据做持久化保存;我们这里只需要存放在一个指定的文本文件中。
项目采用分级菜单方式,每一级菜单应该有“返回主菜单”功能;主菜单有“退出”选项。
记账软件处理的数据,就是收入或者支出的“账目”。每一条账目数据,都应该包含收支类型、金额、备注三部分,这可以构建一个结构体类型 AccountItem 来表示。
而程序运行的开始,应该读取保存在文件中的数据,读取之后应该是一个 AccountItem 类型的数组。
在流程控制方面,如果用户不选择退出,程序就不会结束,所以应该用一个while循环来处理整个流程;当用户确认退出时,更改一个标志位,用来退出循环。
每一级菜单做键盘选择后,可以用 switch 分支语句来处理;不同的功能模块,可以包装成函数。
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):"; }