c语言笔记之小项目家庭收支记账软件

项目1——家庭收支记账软件

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

1.1 需求说明

1.1.1 菜单显示

进入系统,展示主菜单,输入各功能对应的数字编号选择要进行的操作,如下图:

在这里插入图片描述

1.1.2 登记收入

输入2,进入“登记收入”,需输入“本次收入金额”和“本次收入说明”,输入完成后会再次进入主菜单。

在这里插入图片描述

1.1.3 登记支出

输入3,进入“登记支出”,需输入“本次支出金额”和“本次支出说明”,输入完成后会判断余额是否充足,如果余额充足会再次进入主菜单。

在这里插入图片描述

如果余额不足,会给出相应的提示。

在这里插入图片描述

1.1.4 显示收支明细

输入1,进入“收支明细”,如下图所示:”

在这里插入图片描述

当没有任何收支明细时,提示"当前没有收支明细… 来一笔吧!"
在这里插入图片描述

显示完收支明细,会再次进入主菜单。

1.1.5 退出

用户输入4退出时,给出提示"你确定要退出吗? y/n",必须输入正确的y/n ,否则循环输入指令,直到输入y或者n。

在这里插入图片描述

1.2 流程分析

1.2.1 总流程图

在这里插入图片描述

1.2.2 登记收入流程图

在这里插入图片描述

1.2.3 登记支出流程图

在这里插入图片描述

1.2.4 收支明细流程图

在这里插入图片描述

1.2.5 退出流程图

在这里插入图片描述

回顾内容:

1.c语言规定的循环结构有哪些?

​ for/while/do…while

2.熟悉三种循环结构的使用场景

​ 三种循环结构可以相互转换

3.循环结构的4个基本要素

​ ①初始化条件

​ ②循环条件

​ ③循环体

​ ④迭代条件

4.格式

for(;;){}while(){
    ③
    ④
}do{
    ③
    ④
}while();

5.循环结构退出的情况都有哪些?

1.迭代循环条件返回0,false

2.使用break结束,循环的执行

6.c语言中的分支结构有哪些?

>if   if..else     switch-case结构

7.如上的两种分支结构如何选择?

凡是可以使用switch-case实现的结构都可以改写为if-else。反之不成立

switch-case,针对于有限的类型,且变量取值情况不多的场景。

此外的情况,都默认选择if-else

/**
 * 完成项目1,家庭收支记账软件,
 * 1.整体框架搭建
 * 2.完成退出功能
 *   收支明细
 *   登记收入
 *   登记支出,(关于余额的判断)
 * 
 * 难点关注:
 * 1.关于字符串的处理
 *      >字符串变量的声明:①char型数组 ② 字符指针③④ 
 *          char型数组可以修改细微的内容,但是字符指针不行
 *          数组一旦初始化地址是不能变的,字符指针是一个变量,地址是可以变的
 *      >字符串相关的函数:
 *          strcat():字符串的连接
 *          strcpy()
 *          strcmp():比较大小
 * 2.关于输入,输出相关的函数:
 *      scanf()/printf()
 *      getchar()/putchar()------>用的少
 *      puts()/gets()---->fgets()
 *      sprintf()/sscanf()---->输出到字符串
 * 
 * 重点关注:
 * 代码逻辑!比以前单独练习代码量更大,逻辑更复杂。
 * 
*/
#include <stdio.h>
#include <string.h>
/**
 * 对代码进行升级
 *
 */

// 声明结构体
struct FamilyAccount
{
    int hasRecord;      // 默认情况下没有收入或支出的明细
    char details[3000]; // 用来存储收支的记录信息
    double initBalance;
};
int loop = 1;

/**
 * 退出功能
 */
void goExit()
{
    printf("你确定要退出吗(y/n):");
    char isExit;

    while (1)
    {
        scanf("%c", &isExit);
        scanf("%c", &isExit);
        if (isExit == 'y' || isExit == 'n')
        {
            break;
        }
        else
        {
            printf("你输入有误,请重新输入(y/n):");
        }
    }
    if (isExit == 'y')
    {
        loop = 0;
        printf("欢迎再次来到家庭记账软件");
    }
}

/**
 * 显示收支明细
 */

void showDetails(struct FamilyAccount *fAccount)
{
    if (!fAccount->hasRecord)
    {
        printf("当前没有收支明细.....来一笔吧!");
    }
    else
    {

        printf("%s\n", fAccount->details);
    }
}

/**
 * 登记收入
 */

void income(struct FamilyAccount *fAccount)
{

    double addMoney;
    printf("本次收入金额:");
    scanf("%lf", &addMoney);
    printf("本次收入说明:");
    char addDetail[100];
    scanf("%s", addDetail);

    (*fAccount).initBalance += addMoney;
    // 将用户的输入信息拼接为一个完整的字符串
    char addDetails[300];
    sprintf(addDetails, "收入\t%.2f\t\t%.2f\t\t\t%s\n", addMoney, fAccount->initBalance, addDetail);

    // 将用户完整收入的信息添加到当前整体用户收支明细
    strcat(fAccount->details, addDetails);
    // 收入的登记情况
    fAccount->hasRecord = 1;
    printf("登记收入完成\n");
}

/**
 * 登记收入
*/

void pay(struct FamilyAccount *fAccount){

    printf("本次指出金额:");
            double minusMoney;
            scanf("%lf", &minusMoney);
            if (minusMoney > fAccount->initBalance)
            {
                printf("余额不足\n");
            }
            else
            {
                fAccount->initBalance -= minusMoney;
                printf("本次支出说明:");
                char minusDetail[100];
                scanf("%s", minusDetail);

                // 将用户输入的信息拼接为一个完整的字符串
                char minusDetails[300];
                sprintf(minusDetails, "支出\t%.2f\t\t%.2f\t\t\t%s\n", minusMoney, fAccount->initBalance, minusDetail);

                // 将用户完整收入的信息添加到当前整体用户收支明细里
                strcat(fAccount->details, minusDetails);
                fAccount->hasRecord = 1;
                printf("登记支出完成\n");
            }


}
void menu(struct FamilyAccount *fAccount)
{

    do
    {
        printf("-----------------家庭收支记账软件-----------------\n");
        printf("                 1 收支明细\n");
        printf("                 2 登记收入\n");
        printf("                 3 登记支出\n");
        printf("                 4 退    出\n");
        printf("                 请选择(1-4):\n");

        int selection; // 记录用户的选择
        scanf("%d", &selection);

        switch (selection)
        {
        case 1:
            showDetails(fAccount);
            break;

        case 2:
            income(fAccount);
            break;
        case 3:
            pay(fAccount);
            break;
        case 4:
            goExit();
            break;
        default:
            printf("输出错误请重新输入!\n");
            getchar();
            break;
        }

    } while (loop);

    printf("退出");
}

int main()
{

    // 声明结构体变量
    struct FamilyAccount fAccount;
    fAccount.hasRecord = 0;
    // fAccount.details = "-----------------当前收支明细记录-----------------\n收支\t收支金额\t账户金额\t\t说明\n";
    // 数组不能重新赋值,所以会报错,可以改成指针
    strcpy(fAccount.details, "-----------------当前收支明细记录-----------------\n收支\t收支金额\t账户金额\t\t说明\n");

    fAccount.initBalance = 1000;

    // 显示界面
    menu(&fAccount);

    getchar();
    getchar();

    return 0;
}


  • 31
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值