C语言小程序——家庭收支记账软件

实现一个家庭收支记账软件,能够登记收入、登记支出,可以展示收支明细。

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值