目的:利用c++编写一个记账簿软件,实现得功能有记账功能,查询功能
头文件common.h,该头文件包含了改项目所需的多个头文件。以及多个通用函数的定义。
#pragma once
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
#define INCOME "收入"
#define EXPAND "支出"
#define FILENAME "E:\\data\\AccountBook.txt"
using namespace std;
//通用功能性函数声明
//绘制菜单的函数
void showMainMeun();
void showAccountingMeun();
void showQueryMeun();
//读取键盘输入进行合法性校验的函数
char readMeunSelection(int options);
char readQuitConfirm();
int readAmount();
头文件account_item.h,该头文件包含了所需的结构体类型,以及对账目数据进行处理的函数定义。`
#pragma once
#include"common.h"
//定义结构体类型
struct AccountItem
{
string itemType;
int amount;
string detail;
};
//针对账目数据进行操作的函数声明
//加载账目数据
void loadDataFromFile(vector<AccountItem>& items);
//记账
void accounting(vector<AccountItem>& items);
void income(vector<AccountItem>& items);
void expand(vector<AccountItem>& items);
void insertIntoFile(const AccountItem& item);
//查询
void query(const vector<AccountItem>& items);
void queryItems(const vector<AccountItem>& items);
void printItem(const AccountItem& item);
void queryItems(const vector<AccountItem>& items, const string itemType);
编写主函数account.cpp,该函数里面包含了该项目实现的所有流程,以及所用到的所有函数。
#include "common.h"
#include "account_item.h"
int main()
{
//加载文件中的账目数据
vector<AccountItem> items;
loadDataFromFile(items);
bool qiut = false;
while (!qiut)
{
//显示主菜单
showMainMeun();
//读取键盘选择,并做合法性校验
char key = readMeunSelection(3);//菜单中有三个选项
switch (key)
{
case '1'://1-记账
showAccountingMeun();
accounting(items);
break;
case '2'://2-查询
showQueryMeun();
query(items);
case '3'://3-退出
cout << "\n确认退出?(Y/N):";
if (readQuitConfirm() == 'Y')
qiut = true;
break;
default:
break;
}
cout << endl;
}
}
编写菜单函数menus.cpp,该函数里面包含了三个软件界面的菜单,主界面菜单showMainMeun(),记账菜单showAccountingMwun(),查询菜单showQueryMeun(),该函数比较简单,主要就是用到了cout输出。
#include "common.h"
void showMainMeun()
{
system("cls");
cout << "------------------------------------------------" << endl;
cout << "|==============欢迎使用小成记账簿==============|" << endl;
cout << "| |" << endl;
cout << "|*************** 1 记 账 **************|" << endl;
cout << "|*************** 2 查 询 **************|" << endl;
cout << "|*************** 3 退 出 **************|" << endl;
cout << "------------------------------------------------" << endl;
cout << "\n请选择(1-3):";
}
void showAccountingMeun()
{
cout << "------------------------------------------------" << endl;
cout << "|============== 选择记账种类 ==============|" << endl;
cout << "| |" << endl;
cout << "|*************** 1 收 入 **************|" << endl;
cout << "|*************** 2 支 出 **************|" << endl;
cout << "|*************** 3 返回主菜单 **************|" << endl;
cout << "------------------------------------------------" << endl;
cout << "\n请选择(1-3):";
}
void showQueryMeun()
{
cout << "------------------------------------------------" << endl;
cout << "|============== 选择查询条件 ==============|" << endl;
cout << "| |" << endl;
cout << "|*************** 1 统计所有账目 ***************|" << endl;
cout << "|*************** 2 统计收入 ***************|" << endl;
cout << "|*************** 3 统计支出 ***************|" << endl;
cout << "|*************** 4 返回主菜单 **************|" << endl;
cout << "------------------------------------------------" << endl;
cout << "\n请选择(1-4):";
}
编写键盘输入函数read_input.cpp,该函数主要包含对键盘输入的字符型表变量和整形变量进行读取和校验。主要用到了按行读取的API函数getline(cin,str)。
#include "common.h"
//读取键盘输入的菜单选项,进行合法性校验
char readMeunSelection(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 str[0];
}
//读取键盘金额数,并做合法性校验
int readAmount()
{
int amount;
string str;
while (true)
{
getline(cin, str);//获取键盘输入
//进行合法性校验
try
{
amount = stoi(str);
break;
}
catch (invalid_argument e)
{
cout << "输入错误,请输入正确的数字:";
}
}
//输入合法
return amount;
}
最后一个函数是对账目数据进行操作的函数operations.cpp,这个函数是最重要的也是最复杂的函数,主要实现对账目数据的读取,记账,查询以及保存功能。
读取账目数据,是通过fstream input(FILENAME),函数来实现对账目文件的操作。
保存账目数据进入txt文件,用到了ofstream output(FILENAME,ios::out|ios::app);创建一个流对象,以追加的方式进行写入。
记录账目数据包含两大部分,收入和支出,主要思想就是通过按键输入,将输入的数据存到创建的结构体变量中,在将变量保存在容器中,方便保存进txt文件。
查询账目数据用到了for(auto item : items){}遍历整个容器,并统计总收支,并输出结果。另外统计总收支用到了函数重载,因为有总收入和总支出两个统计量。
整个代码如下:
#include "common.h"
#include"account_item.h"
//读取文件中的账目数据
void loadDataFromFile(vector<AccountItem>& items)
{
ifstream input(FILENAME);
//逐行读取每一条账目,包装成AccountItem
AccountItem item;
while (input>>item.itemType>>item.amount>>item.detail)
{
items.push_back(item);
}
input.close();
}
//记账操作
void accounting(vector<AccountItem>& items)
{
//读取键盘选择,并做合法性校验
char key = readMeunSelection(3);//菜单中有三个选项
switch (key)
{
case '1'://1-收入
income(items);
break;
case '2'://2-支出
expand(items);
break;
//case '3'://3-退出
// break;
default:
break;
}
cout << endl;
}
//记录一笔收入
void income(vector<AccountItem>& items)//接收一个类型为vector<AccountItem>的参数items,用引用传递意味着函数将直接操作调用者提供的实际vector对象
{
//新构建一个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 insertIntoFile(const AccountItem& item)
{
//创建一个ofstream对象,以追加方式进行写入
ofstream output(FILENAME,ios::out | ios::app);
output << item.itemType << "\t" << item.amount << "\t" << item.detail << endl;
output.close();
}
//记录一笔支出
void expand(vector<AccountItem>& items)
{
//新构建一个AccountItem对象
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;
string line;
getline(cin, line);
}
void query(const vector<AccountItem>& items)
{
//读取键盘选择,并做合法性校验
char key = readMeunSelection(4);//菜单中有三个选项
switch (key)
{
case '1'://1-查询所有账目,并统计总收支
queryItems(items);
break;
case '2'://2-查询收入,统计总收入
queryItems(items,INCOME);
break;
case '3'://3-查询支出,统计总支出
queryItems(items, EXPAND);
break;
default:
break;
}
cout << endl;
}
//查询账目功能函数
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" << endl;
cout << "总收支:" << total << endl;
cout << "\n请按回车键返回主菜单..." << endl;
string line;
getline(cin,line);
}
//打印输出一条账目信息
void printItem(const AccountItem& item)
{
cout << item.itemType << "\t" << item.amount << "\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) {
printItem(item);
total += item.amount;
}
}
//输出信息
cout << "=========================================\n" << endl;
cout << ((itemType == INCOME)?"总收支:" :"总支出:" )<< total << endl;
cout << "\n请按回车键返回主菜单..." << endl;
string line;
getline(cin, line);
}