财务管理系统

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//定义链表节点
typedef struct RecordNode {
    int year, month, day; //记录日期
    float amount; //金额
    int type; //支出种类,0表示收入,1表示支出
    char detail[100]; //详细描述
    struct RecordNode *next; //指向下一个节点的指针
} RecordNode;

//显示菜单
void showMenu() {
    printf("1. 添加收入记录\n");
    printf("2. 添加支出记录\n");
    printf("3. 查看收支情况\n");
    printf("4. 设置预算\n");
    printf("5. 管理预算\n");
    printf("6. 生成报表统计\n");
    printf("7. 可视化展示\n");
    printf("8. 退出\n");
    printf("请选择:\n");
}

//添加记录
RecordNode* addRecord(RecordNode *head) {
    RecordNode *p, *q;
    q = (RecordNode*)malloc(sizeof(RecordNode)); //为新节点分配内存
    printf("请输入年月日,格式为yyyy-mm-dd:\n");
    scanf("%d-%d-%d", &q->year, &q->month, &q->day);
    printf("请输入金额:\n");
    scanf("%f", &q->amount);
    printf("请选择类型(0表示收入,1表示支出):\n");
    scanf("%d", &q->type);
    printf("请输入详细描述:\n");
    scanf("%s", q->detail);
    q->next = NULL;
    //找到链表尾部,并将新节点添加到链表末尾
    if (head == NULL) {
        head = q;
    }
    else {
        p = head;
        while (p->next != NULL) {
            p = p->next;
        }
        p->next = q;
    }
    printf("记录添加成功!\n");
    return head;
}

//查看收支情况
void showRecord(RecordNode *head) {
    RecordNode *p;
    float income = 0, expense = 0; //收入和支出金额
    printf("日期\t\t\t金额\t\t类型\t\t描述\n");
    for (p = head; p != NULL; p = p->next) {
        printf("%d-%02d-%02d\t%.2f\t\t", p->year, p->month, p->day, p->amount);
        if (p->type == 0) {
            printf("收入\t\t");
            income += p->amount;
        }
        else {
            printf("支出\t\t");
            expense += p->amount;
        }
        printf("%s\n", p->detail);
    }
    printf("总收入为:%.2f元,总支出为:%.2f元,净收入为:%.2f元\n", income, expense, income - expense);
}

//设置预算
void setBudget(float *budget) {
    printf("请输入本月预算:\n");
    scanf("%f", budget);
    printf("预算设置为:%.2f元\n", *budget);
}

//管理预算
void manageBudget(RecordNode *head, float budget) {
    RecordNode *p;
    float totalExpense = 0; //当月总支出
    int controlFlag = 0; //是否需要控制支出的标志
    for (p = head; p != NULL; p = p->next) {
        if (p->year == 2022 && p->month == 1) { //只统计当前月的记录
            if (p->type == 1) {
                totalExpense += p->amount;
                if (p->amount > budget / 30) { //超出每日预算50元,需要控制支出
                    controlFlag = 1;
                }
            }
        }
    }
    printf("本月总支出为:%.2f元,预算剩余:%.2f元\n", totalExpense, budget - totalExpense);
    if (controlFlag) {
        printf("警告:某些支出超过每日控制金额,需要控制支出!\n");
    }
}

//生成报表统计
void generateReport(RecordNode *head) {
    int incomeCount = 0, expenseCount = 0;
    float incomeSum = 0, expenseSum = 0;
    int typeCount[10] = { 0 }; //不同类型的支出数量,最多支持10种类型
    RecordNode *p;
    for (p = head; p != NULL; p = p->next) {
        if (p->type == 0) {
            incomeSum += p->amount;
            incomeCount++;
        }
        else {
            expenseSum += p->amount;
            expenseCount++;
            typeCount[p->type - 1]++;
        }
    }
    printf("报表统计如下:\n");
    printf("当月总收入为:%.2f元,总支出为:%.2f元,净收入为:%.2f元\n", incomeSum, expenseSum, incomeSum - expenseSum);
    printf("当月共有%d条收入记录,%d条支出记录\n", incomeCount, expenseCount);
    printf("支出类别如下:\n");
    for (int i = 0; i < 10; i++) {
        if (typeCount[i] != 0) {
            printf("支出类别%d:%.2f元,占比%.2f%%\n", i + 1, typeCount[i], typeCount[i] * 100.0 / expenseCount);
        }
    }
}

//可视化展示
void visualize(RecordNode *head) {
       int count[10] = { 0 }; //不同类型支出的数量
    float expense = 0; //总支出
    RecordNode *p;
    //统计不同类型支出的数量和总支出
    for (p = head; p != NULL; p = p->next) {
        if (p->type == 1) { //只统计支出
            expense += p->amount;
            count[p->type - 1]++; //支出类型从1开始,需要减1对应数组下标
        }
    }
    printf("当前月份支出总额为:%.2f元\n", expense);
    printf("支出类别比例如下:\n");
    //输出饼图
    float percent;
    for (int i = 0; i < 10; i++) {
        if (count[i] != 0) {
            percent = count[i] * 100.0 / expense; //计算支出占比
            printf("类型%d:", i + 1);
            for (int j = 1; j <= percent / 2; j++) { //占比每增加2%,输出一个"*"
                printf("*");
            }
            printf(" %.2f%%\n", percent);
        }
    }
}

int main() {
    RecordNode *head = NULL; //链表为空
    int choice;
    float budget = 0; //预算初始值为0
    do {
        showMenu();
        scanf("%d", &choice);
        switch (choice) {
        case 1:
            head = addRecord(head);
            break;
        case 2:
            head = addRecord(head);
            break;
        case 3:
            showRecord(head);
            break;
        case 4:
            setBudget(&budget);
            break;
        case 5:
            manageBudget(head, budget);
            break;
        case 6:
            generateReport(head);
            break;
        case 7:
            visualize(head);
            break;
        case 8:
            printf("感谢使用,再见!\n");
            break;
        default:
            printf("输入有误,请重新输入!\n");
            break;
        }
    } while (choice != 8);
    //释放链表内存
    RecordNode *p = head, *q;
    while (p != NULL) {
        q = p->next;
        free(p);
        p = q;
    }
    return 0;
}

欢迎订阅专栏,数据结构实验,期末大作业,前端后端都有哦,想我发哪个方面的资源或文章可以私信我,免费的哦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

然然超绝肌肉线条

你的鼓励将是创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值