永远Forever 发表于 2023-5-6 11:52:57

新手管理系统有个功能不知道怎么加

新手第一次写管理系统中很多地方写的差不多了
然后我在后面发现有个自动计算余额的功能还没有写上去
本人也是刚刚接触链表的结构
现在磨了好一会还是没有头绪应该怎么加上去
大佬们可以给点建议吗
下面是贴的码

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <malloc.h>


int mainMenu();
void addItem();
void showAllItem();
void searchItem();
void modifyItem();
void delItem();

typedef struct Datetime
{
        int year;
        int month;
        int day;
}Datetime;

typedef struct ClassFee
{
        int cf_num;                                        //编号
        char IE;                                //收支情况
        char name;            //经办人
        char result;                        //原因
        intavg;                   //金额(每位同学)
        int number;                                        //人数
        int Balance;                                //余额(自动生成)
        char remake;                                //备注
        Datetime time;                                //时间
}ClassFee, Data;

typedef struct Node
{
        Data data;                                //数据域
        struct Node* next;                //指针域
}Node;

//链表结构
typedef struct List
{
        size_t size;                //数据节点个数
        Node* front;                //头指针
        Node* tail;                        //尾指针
}List;
void cf_printf(ClassFee cf)
{
        printf("%03d        %s        %s        %s        %d        %d        %d %s\n", cf.cf_num, cf.IE, cf.name, cf.result, cf.avg, cf.number, cf.Balance, cf.remake);
}
//定义节点
//创建链表
List* createList();
//销毁链表
void destroyList(List* list);
//插入数据
void push_back(List* list, Data val);
//删除数据
typedef bool(*CMP)(Data*, Data*);
void remove_if(List* list, CMP cmp, Data* val);
//遍历链表
typedef void (*DoSomething)(Data*);
void for_each(List* list, DoSomething dos);

List* glist = NULL;

List* createList()       //创建链表
{
        List* list = (List*)calloc(1, sizeof(List));
        if (!list)
        {
                return NULL;
        }
        //申请头节点
        list->front = list->tail = (Node*)calloc(1, sizeof(Node));
        if (!list->front)
        {
                return NULL;
        }
        return list;
}
void push_back(List* list, Data val)
{
        //申请新节点
        Node* newNode = (Node*)calloc(1, sizeof(Node));
        if (!newNode)
        {
                return;
        }
        newNode->data = val;
        //插入
        list->tail->next = newNode;
        list->tail = newNode;
        list->size++;
        list->tail->next = NULL;
}

void destroyList(List* list)                        //销毁链表
{
        Node* p = list->front;
        while (p)
        {
                Node* next = p->next;
                free(p);
                p = next;
        }
        free(list);
}


void searchItem()
{
        int num;
        printf("请输入要查询的编号:");
        scanf("%d", &num);
        Node* p = glist->front->next;
        while (p)
        {
                if (p->data.cf_num == num)
                {
                        cf_printf(p->data);
                        return;
                }
                p = p->next;
        }
        printf("没有找到!\n");
}

void modifyItem()
{
        int num;
        printf("请输入要修改的编号:");
        scanf("%d", &num);
        Node* p = glist->front->next;
        while (p)
        {
                if (p->data.cf_num == num)
                {
                        printf("请输入修改后的数据:\n");
                        printf("收支情况:");
                        scanf("%s", p->data.IE);
                        printf("经办人:");
                        scanf("%s", p->data.name);
                        printf("原因:");
                        scanf("%s", p->data.result);
                        printf("金额(每位同学):");
                        scanf("%d", &p->data.avg);
                        printf("人数:");
                        scanf("%d", &p->data.number);
                        printf("备注:");
                        scanf("%s", p->data.remake);
                        printf("修改成功!\n");
                        return;
                }
                p = p->next;
        }
        printf("没有找到!\n");
}

void delItem()
{
        int num;
        printf("请输入要删除的编号:");
        scanf("%d", &num);
        Node* p = glist->front;
        while (p->next)
        {
                if (p->next->data.cf_num == num)
                {
                        Node* del = p->next;
                        p->next = del->next;
                        if (del == glist->tail)
                        {
                                glist->tail = p;
                        }
                        free(del);
                        del = NULL;
                        glist->size--;
                        printf("删除成功!\n");
                        return;
                }
                p = p->next;
        }
        printf("没有找到!\n");
}

void for_each(List* list, DoSomething dos)
{
        Node* p = list->front->next;
        while (p)
        {
                dos(&p->data);
                p = p->next;
        }
}

void showAllItem()                                        //浏览所有班费信息
{
        Node* curNode = glist->front->next;
        while (curNode)
        {
                printf("班费收支编号        收入或支出        经办人        原因        金额(每位同学)        人数        余额        备注\n");
                cf_printf(curNode->data);
                curNode = curNode->next;
        }
}



int main()
{
        glist = createList();
        bool isDone = false;
        while (!isDone)
        {
                switch (mainMenu())      //根据具体的功能处理
                {
                case 6:                  //退出系统
                        isDone = true;
                        break;
                case 1:
                        addItem();                        //录入班费信息
                        break;
                case 2:
                        showAllItem();                //浏览所有班费信息
                        break;
                case 3:
                        searchItem();                //查找班费信息
                        break;
                case 4:
                        modifyItem();                //修改班费信息
                        break;
                case 5:
                        delItem();                        //删除班费信息
                        break;
                default:
                        printf("请输入正确的选项☆");
                        break;
                }
                system("pause");
                system("cls");
        }
        destroyList(glist);
        return 0;
}

int mainMenu()                        //主菜单
{
        printf("         班级收支管理系统\n");
        printf("☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n");
        printf(" ☆                                        ★ \n");
        printf(" ☆         1.录入班费信息               ★ \n");
        printf(" ☆         2.浏览所有班费信息                  ★ \n");
        printf(" ☆         3.查询班费信息                  ★ \n");
        printf(" ☆         4.修改班费信息                  ★ \n");
        printf(" ☆         5.删除班费信息                  ★ \n");
        printf(" ☆         6.退出系统                          ★ \n");
        printf(" ☆                                        ★ \n");
        printf("★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★\n");
        printf("请选择要执行的功能:");
        int op;
        int ret = scanf("%d", &op);

        return op;
}

void addItem()                                                //录入班费信息
{
        ClassFee cf;
        printf("请输入班费收支编号: ");
        scanf("%03d", &cf.cf_num);
        printf("收入还是支出: ");
        scanf("%s", &cf.IE);
        printf("请输入经办人姓名: ");
        scanf("%s", &cf.name);
        printf("请输入原因: ");
        scanf("%s", &cf.result);
        printf("请输入金额(每位同学): ");
        scanf("%d", &cf.avg);
        printf("请输入人数: ");
        scanf("%d", &cf.number);
        //打印出自动生成的余额
       
        printf("%d", &cf.Balance);
        printf("请输入备注:");
        scanf("%s", &cf.remake);

        printf("班费收支编号        收入或支出        经办人        原因        金额(每位同学)        人数        余额        备注\n");
        push_back(glist, cf);
        cf_printf(cf);

}

isdkz 发表于 2023-5-6 11:57:21

首先,为了实现自动计算余额的功能,我们需要在链表结构中添加一个表示总余额的变量。然后,在录入新的班费信息时,根据收支情况更新总余额。最后,将新的余额赋值给当前班费信息的余额字段。以下是修改后的代码:

typedef struct List
{
      size_t size;                //数据节点个数
      Node* front;                //头指针
      Node* tail;                        //尾指针
      int total_balance;          //总余额
}List;

void update_balance(List* list, Data val) {
    if (strcmp(val.IE, "收入") == 0) {
      list->total_balance += val.avg * val.number;
    } else if (strcmp(val.IE, "支出") == 0) {
      list->total_balance -= val.avg * val.number;
    }
}

void push_back(List* list, Data val)
{
      // 更新总余额
      update_balance(list, val);
      // 将当前总余额赋值给当前班费信息的余额字段
      val.Balance = list->total_balance;

      //申请新节点
      Node* newNode = (Node*)calloc(1, sizeof(Node));
      if (!newNode)
      {
                return;
      }
      newNode->data = val;
      //插入
      list->tail->next = newNode;
      list->tail = newNode;
      list->size++;
      list->tail->next = NULL;
}

void addItem()                                                //录入班费信息
{
      ClassFee cf;
      printf("请输入班费收支编号: ");
      scanf("%03d", &cf.cf_num);
      printf("收入还是支出: ");
      scanf("%s", cf.IE);
      printf("请输入经办人姓名: ");
      scanf("%s", cf.name);
      printf("请输入原因: ");
      scanf("%s", cf.result);
      printf("请输入金额(每位同学): ");
      scanf("%d", &cf.avg);
      printf("请输入人数: ");
      scanf("%d", &cf.number);
      // 自动生成的余额将在 push_back 函数中更新
      
      printf("请输入备注:");
      scanf("%s", cf.remake);

      printf("班费收支编号      收入或支出      经办人      原因      金额(每位同学)      人数      余额      备注\n");
      push_back(glist, cf);
      cf_printf(cf);

}


这样,你的代码现在应该可以自动计算余额了。在录入新的班费信息时,程序会根据收支情况更新总余额,然后将新的余额赋值给当前班费信息的余额字段。

永远Forever 发表于 2023-5-6 12:47:13

isdkz 发表于 2023-5-6 11:57
首先,为了实现自动计算余额的功能,我们需要在链表结构中添加一个表示总余额的变量。然后,在录入新的班费 ...

谢谢大佬的指点,已解决自动计算的问题,还有一个小bug烦请大佬看看,就是录入后打印的时候,那个余额是一串凌乱的数据,是哪里出问题的呀

harrydeng 发表于 2023-5-6 13:49:35

谢谢大佬的指点,已解决自动计算的问题,还有一个小bug烦请大佬看看,就是录入后打印的时候,那个余额是一串凌乱的数据,是哪里出问题的呀
页: [1]
查看完整版本: 新手管理系统有个功能不知道怎么加