实现一个家庭收支记账软件,能够登记收入、登记支出,可以展示收支明细。
1.项目需求
1.1菜单显示
进入系统,展示主菜单,输入各功能对应的数字编号选择要进行的操作,如下图:
1.2登记收入
输入2,进入“登记收入”,需输入“本次收入金额”和“本次收入说明”,输入完成后会再次进入主菜单。
1.3登记支出
输入3,进入“登记支出”,需输入“本次支出金额”和“本次支出说明”,输入完成后会判断余额是否充足,如果余额充足会再次进入主菜单。
如果余额不足,会给出相应的提示。
1.4显示收支明细
输入1,进入“收支明细”,如下图所示:
当没有任何收支明细时,提示"当前没有收支明细... 来一笔吧!"
显示完收支明细,会再次进入主菜单。
1.5退出
用户输入4退出时,给出提示"你确定要退出吗? y/n",必须输入正确的y/n ,否则循环输入指令,直到输入y或者n。
2.流程分析
2.1总流程图
2.2各个子流程图
3.代码实现
#include <stdio.h>
#include <string.h>
int main()
{
// 定义相关的变量
int key = 0; // 表示用户输入了哪个菜单 1:收支明细 2:登记收入 3:登记支出 4:退出
int loop = 1; // 控制是否退出菜单
char details[3000] = "-----------------当前收支明细记录-----------------\n"
"收支\t收支金额\t账户金额 \t说 明"; // 记录所有的收入和支出情况
char note[20] = ""; // 对收入或者支出的说明
char temp[100] = ""; // 是用于格式化每次的收入或者支出,然后拼接到details
double money = 0.0;
double balance = 1000.0; // 账号余额, 初始化为1000.0
char choice = ' '; // 表示用户选择的是y/n
int flag = 0; // 表示是否有至少一笔收入或者支出
do
{
printf("\n\n---------家庭收支记账软件-----------------");
printf("\n 1 收支明细");
printf("\n 2 登记收入");
printf("\n 3 登记支出");
printf("\n 4 退 出");
printf("\n 请选择(1-4):");
scanf("%d", &key);
switch (key)
{
case 1:
if (flag)
{
printf("%s", details);
}
else
{
printf("\n当前没有收支明细... 来一笔吧!");
}
break;
case 2:
printf("\n本次收入金额:");
scanf("%lf", &money);
balance += money; // 更新余额
printf("\n本次收入说明:");
scanf("%s", note);
sprintf(temp, "\n收入\t%.2f\t\t%.2f\t\t%s", money, balance, note); // 将本次信息,写入到temp字符数组
// 将信息拼接到 details
strcat(details, temp);
flag = 1;
break;
case 3:
printf("\n本次支出金额:");
scanf("%lf", &money);
// 判断是否够支出
if (money > balance)
{ // 不够
printf("\n 余额不足...");
break;
}
printf("\n本次支出说明:");
scanf("%s", note);
balance -= money;
sprintf(temp, "\n支出\t%.2f\t\t%.2f\t\t%s", money, balance, note); // 将本次信息,写入到temp字符数组
// 将信息拼接到 details
strcat(details, temp);
flag = 1;
break;
case 4:
printf("\n你确定要退出吗(y/n):");
do
{
scanf("%c", &choice);
if (choice == 'y' || choice == 'n')
{
break;
}
printf("\n你的输入有误,请重新输入(y/n):");
} while (1);
if (choice == 'y')
{
loop = 0;
}
}
} while (loop);
printf("你退出了家庭财务软件~~");
return 0;
}
10月6日上传,优化了代码,使用结构体完成,并且使用函数来提高项目的模块化编程。
优化代码
#include <stdio.h>
#include <string.h>
// 定义一个结构体
struct MyFamilyAccount
{
int flag; // 表示是否有至少一笔收入或者支出
char details[3000]; // 明细
double balance; // 余额
};
// 定义相关的变量, 全局变量
int key = 0; // 表示用户输入了哪个菜单
int loop = 1; // 控制是否退出菜单
char note[20] = ""; // 对收入或者支出的说明
char temp[100] = ""; // 是用于格式化每次的收入或者支出,然后拼接到details
double money = 0.0;
char choice = ' '; // 表示用户选择的是y/n
// 使用函数,完成退出
void myExit()
{
printf("\n你确定要退出吗(y/n):");
do
{
scanf("%c", &choice);
if (choice == 'y' || choice == 'n')
{
break;
}
printf("\n你的输入有误,请重新输入(y/n):");
} while (1);
if (choice == 'y')
{
loop = 0;
}
}
// 使用函数,显示明细
void showDetails(struct MyFamilyAccount *myFamilyAccount)
{
if ((*myFamilyAccount).flag)
{
printf("%s", (*myFamilyAccount).details);
}
else
{
printf("\n当前没有收支明细... 来一笔吧!");
}
}
// 使用函数,完成登记收入, 封装
void income(struct MyFamilyAccount *myFamilyAccount)
{
printf("\n本次收入金额:");
scanf("%lf", &money);
(*myFamilyAccount).balance += money; // 更新余额
printf("\n本次收入说明:");
scanf("%s", note);
sprintf(temp, "\n收入\t%.2f\t\t%.2f\t\t%s", money,
(*myFamilyAccount).balance, note); // 将本次信息,写入到temp字符数组
// 将信息拼接到 details
strcat((*myFamilyAccount).details, temp);
(*myFamilyAccount).flag = 1;
}
// 完成一个登记支出
void pay(struct MyFamilyAccount *myFamilyAccount)
{
printf("\n本次支出金额:");
scanf("%lf", &money);
// 判断是否够支出
if (money > (*myFamilyAccount).balance)
{ // 不够
printf("\n余额不足...");
return;
}
printf("\n本次支出说明:");
scanf("%s", note);
(*myFamilyAccount).balance -= money;
sprintf(temp, "\n支出\t%.2f\t\t%.2f\t\t%s", money,
(*myFamilyAccount).balance, note); // 将本次信息,写入到temp字符数组
// 将信息拼接到 details
strcat((*myFamilyAccount).details, temp);
(*myFamilyAccount).flag = 1;
}
// 函数专门显示菜单
void mainMenu(struct MyFamilyAccount *myFamilyAccount)
{
do
{
printf("\n\n---------家庭收支记账软件-----------------");
printf("\n 1 收支明细");
printf("\n 2 登记收入");
printf("\n 3 登记支出");
printf("\n 4 退 出");
printf("\n 请选择(1-4):");
scanf("%d", &key);
switch (key)
{
case 1:
showDetails(myFamilyAccount);
break;
case 2:
income(myFamilyAccount);
break;
case 3:
pay(myFamilyAccount);
break;
case 4:
myExit();
}
} while (loop);
printf("你退出了家庭财务软件~~");
}
int main()
{
// 创建一个结构体变量
struct MyFamilyAccount myFamilyAccount;
// 初始化
myFamilyAccount.flag = 0;
myFamilyAccount.balance = 1000.0;
// 使用拷贝的方式赋值
strcpy(myFamilyAccount.details,
"-----------------当前收支明细记录-----------------"
"\n收支\t收支金额\t账户金额\t说 明");
// 调用mainMenu 显示菜单
mainMenu(&myFamilyAccount);
return 0;
}