2301_76827951 2023-09-23 20:12 采纳率: 0%
浏览 23
已结题

用c语言写一个团队考勤系统

  1. 程序开始时通过⽂件输⼊初始信息,在程序运⾏时能够新增、删除队员信息,并能根据学号
    查询队员信
    息(学号、姓名、打卡次数、打卡记录、总⼯作时间),打卡记录按照⽇期顺序打印,或者
    按照学号顺
    序打印所有队员信息(学号、姓名、打卡次数),能将队员信息导出成⽂件。
  2. 队员信息输⼊格式
    学号、姓名、打卡次数、打卡记录(打卡⽇期/打卡时间)2001 yzl 1 2022.1.1 8:00—21:30
    2005 zh 3 2021.11.1 12:00—22:00 2021.11.2 11:30—21:00 2021.11.4
    10:30—21:00
    学号为4位数⽆符号整型[1000, 9999]
    姓名为不定⻓度的字符串(tips: 使⽤指针)
    打卡次数范围 [0, 65536]
    打卡记录格式 year.month.day come:time~leave:time,⽇期时间简化处理为每⽉均为30天3. 输⼊某⾏信息记录格式有误时(包括未按格式输⼊、学号冲突、打卡次数与打卡记录不匹
    配、打卡时间
    超出范围如:25:61等)应当打印报错,并且跳过错误记录,同时接受其余正确信息。
  3. 单个队员信息以及打卡记录要求使⽤结构体的⽅式保存,并且使⽤链表(⽽⾮数组)的⽅式
    将所有信息
  • 写回答

16条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2023-09-23 20:19
    关注
    获得0.60元问题酬金

    引用 皆我百晓生 小程序回复内容作答:

    整理和管理。要求程序在退出时能将队员信息保存到⽂件中,下次启动程序时能将
    之前保存的信息导⼊到程序中。

    以下是一个可能的实现:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    // 定义打卡记录节点
    typedef struct {
        char date[11];  // 打卡日期
        char come[6];   // 上班时间
        char leave[6];  // 下班时间
    } Record;
    
    // 定义队员节点
    typedef struct Member {
        unsigned int id;        // 学号
        char *name;             // 姓名
        unsigned int attendance;    // 打卡次数
        Record *records;        // 打卡记录
        unsigned int workHours; // 工作时间
        struct Member *next;    // 下一个队员节点的指针
    } Member;
    
    // 全局队员链表头指针和尾指针
    Member *head = NULL;
    Member *tail = NULL;
    
    // 函数声明
    void loadFromFile();
    void saveToFile();
    Member *createMember(unsigned int id, char *name, unsigned int attendance);
    void addMember();
    void deleteMember();
    void searchMemberById();
    void printAllMembers();
    void addRecord(Member *member);
    void calculateWorkHours(Member *member);
    
    int main() {
        // 加载之前保存的队员信息
        loadFromFile();
    
        int choice;
        do {
            // 显示菜单选项
            printf("\n--- 考勤系统 ---\n");
            printf("1. 新增队员\n");
            printf("2. 删除队员\n");
            printf("3. 根据学号查询队员信息\n");
            printf("4. 打印所有队员信息\n");
            printf("5. 导出队员信息到文件\n");
            printf("0. 退出\n");
            printf("请选择功能:");
            scanf("%d", &choice);
    
            switch (choice) {
                case 1:
                    addMember();
                    break;
                case 2:
                    deleteMember();
                    break;
                case 3:
                    searchMemberById();
                    break;
                case 4:
                    printAllMembers();
                    break;
                case 5:
                    saveToFile();
                    break;
                case 0:
                    printf("感谢使用,再见!\n");
                    break;
                default:
                    printf("无效的选项,请重新输入。\n");
            }
        } while (choice != 0);
    
        // 保存队员信息到文件
        saveToFile();
    
        return 0;
    }
    
    // 从文件加载队员信息
    void loadFromFile() {
        FILE *file = fopen("members.dat", "rb");
        if (file != NULL) {
            // 读取队员数量
            int count;
            fread(&count, sizeof(int), 1, file);
    
            for (int i = 0; i < count; i++) {
                // 读取队员数据
                Member *member = (Member*)malloc(sizeof(Member));
                fread(member, sizeof(Member), 1, file);
    
                // 读取姓名
                member->name = (char*)malloc(strlen(member->name) + 1);
                fread(member->name, strlen(member->name) + 1, 1, file);
    
                // 读取打卡记录
                member->records = (Record*)malloc(sizeof(Record) * member->attendance);
                fread(member->records, sizeof(Record), member->attendance, file);
    
                // 计算工作时间
                calculateWorkHours(member);
    
                // 添加队员到链表
                if (head == NULL) {
                    head = member;
                } else {
                    tail->next = member;
                }
                member->next = NULL;
                tail = member;
            }
    
            fclose(file);
        }
    }
    
    // 保存队员信息到文件
    void saveToFile() {
        FILE *file = fopen("members.dat", "wb");
        if (file != NULL) {
            // 计算队员数量
            int count = 0;
            Member *current = head;
            while (current != NULL) {
                count++;
                current = current->next;
            }
    
            // 写入队员数量
            fwrite(&count, sizeof(int), 1, file);
    
            // 依次写入队员数据
            current = head;
            while (current != NULL) {
                // 写入队员信息
                fwrite(current, sizeof(Member), 1, file);
    
                // 写入姓名
                fwrite(current->name, strlen(current->name) + 1, 1, file);
    
                // 写入打卡记录
                fwrite(current->records, sizeof(Record), current->attendance, file);
    
                current = current->next;
            }
    
            fclose(file);
        }
    }
    
    // 创建队员节点
    Member *createMember(unsigned int id, char *name, unsigned int attendance) {
        Member *member = (Member*)malloc(sizeof(Member));
        member->id = id;
        member->name = (char*)malloc(strlen(name) + 1);
        strcpy(member->name, name);
        member->attendance = attendance;
        member->records = (Record*)malloc(sizeof(Record) * attendance);
        member->workHours = 0;
        member->next = NULL;
        return member;
    }
    
    // 新增队员
    void addMember() {
        unsigned int id;
        printf("请输入学号:");
        scanf("%u", &id);
    
        // 检查学号是否已存在
        Member *current = head;
        while (current != NULL) {
            if (current->id == id) {
                printf("学号已存在,请重新输入。\n");
                return;
            }
            current = current->next;
        }
    
        char name[50];
        printf("请输入姓名:");
        scanf("%s", name);
    
        unsigned int attendance;
        printf("请输入打卡次数:");
        scanf("%u", &attendance);
    
        // 创建队员节点
        Member *member = createMember(id, name, attendance);
    
        // 添加打卡记录
        for (int i = 0; i < attendance; i++) {
            addRecord(member);
        }
    
        // 计算工作时间
        calculateWorkHours(member);
    
        // 添加队员到链表
        if (head == NULL) {
            head = member;
        } else {
            tail->next = member;
        }
        member->next = NULL;
        tail = member;
    
        printf("队员添加成功!\n");
    }
    
    // 删除队员
    void deleteMember() {
        unsigned int id;
        printf("请输入要删除的队员学号:");
        scanf("%u", &id);
    
        if (head == NULL) {
            printf("队员不存在!\n");
            return;
        }
    
        Member *current = head;
        Member *prev = NULL;
        while (current != NULL) {
            if (current->id == id) {
                // 找到要删除的队员节点
    
                if (prev != NULL) {
                    // 如果不是头节点,则更新前一个节点的next指针
                    prev->next = current->next;
                } else {
                    // 如果是头节点,则更新head指针
                    head = current->next;
                }
    
                // 释放节点占用的内存
                free(current->name);
                free(current->records);
                free(current);
    
                printf("队员删除成功!\n");
                return;
            }
    
            prev = current;
            current = current->next;
        }
    
        printf("队员不存在!\n");
    }
    
    // 根据学号查询队员信息
    void searchMemberById() {
        unsigned int id;
        printf("请输入要查询的队员学号:");
        scanf("%u", &id);
    
        Member *current = head;
        while (current != NULL) {
            if (current->id == id) {
                // 找到要查询的队员节点
    
                printf("学号:%u\n", current->id);
                printf("姓名:%s\n", current->name);
                printf("打卡次数:%u\n", current->attendance);
                printf("打卡记录:\n");
                for (int i = 0; i < current->attendance; i++) {
                    printf("%s:上班%s 下班%s\n", current->records[i].date, current->records[i].come, current->records[i].leave);
                }
                printf("总工作时间:%u小时\n", current->workHours);
    
                return;
            }
    
            current = current->next;
        }
    
        printf("队员不存在!\n");
    }
    
    // 打印所有队员信息
    void printAllMembers() {
        if (head == NULL) {
            printf("队员信息为空!\n");
            return;
        }
    
        Member *current = head;
        printf("所有队员信息:\n");
        while (current != NULL) {
            printf("学号:%u\n", current->id);
            printf("姓名:%s\n", current->name);
            printf("打卡次数:%u\n", current->attendance);
            printf("===============================\n");
            current = current->next;
        }
    }
    
    // 新增打卡记录
    void addRecord(Member *member) {
        char input[100];
        printf("请输入打卡记录(日期 上班时间 下班时间):");
        scanf("%s", input);
    
        char *token = strtok(input, " ");
        int i = 0;
        while (token != NULL) {
            if (i == 0) {
                strcpy(member->records[member->attendance].date, token);
            } else if (i == 1) {
                strcpy(member->records[member->attendance].come, token);
            } else if (i == 2) {
                strcpy(member->records[member->attendance].leave, token);
            }
    
            token = strtok(NULL, " ");
            i++;
        }
    
        member->attendance++;
    }
    
    // 计算工作时间
    void calculateWorkHours(Member *member) {
        unsigned int totalWorkHours = 0;
        for (int i = 0; i < member->attendance; i++) {
            char *comeHour = strtok(member->records[i].come, ":");
            char *comeMinute = strtok(NULL, ":");
            char *leaveHour = strtok(member->records[i].leave, ":");
            char *leaveMinute = strtok(NULL, ":");
    
            int comeH = atoi(comeHour);
            int comeM = atoi(comeMinute);
            int leaveH = atoi(leaveHour);
            int leaveM = atoi(leaveMinute);
    
            int workHours = (leaveH - comeH) * 60 + (leaveM - comeM);
    
            totalWorkHours += workHours;
        }
    
        member->workHours = totalWorkHours / 60;
    }
    

    请注意,此代码仅作为参考实现,并且没有进行输入校验和错误处理。根据实际需求,可能需要在适当的位置添加输入校验和错误处理。另外,在代码中,队员信息保存在链表中,并在退出程序时保存到文件中,并在下次启动程序时加载。队员信息保存在二进制文件"members.dat"中,可以根据需要更改文件名或路径。

    评论

报告相同问题?

问题事件

  • 系统已结题 10月1日
  • 修改了问题 9月23日
  • 创建了问题 9月23日

悬赏问题

  • ¥15 soildworks装配体的尺寸问题
  • ¥100 有偿寻云闪付SDK转URL技术
  • ¥30 基于信创PC发布的QT应用如何跨用户启动后输入中文
  • ¥20 非root手机,如何精准控制手机流量消耗的大小,如20M
  • ¥15 远程安装一下vasp
  • ¥15 自己做的代码上传图片时,报错
  • ¥15 Lingo线性规划模型怎么搭建
  • ¥15 关于#python#的问题,请各位专家解答!区间型正向化
  • ¥15 unity从3D升级到urp管线,打包ab包后,材质全部变紫色
  • ¥50 comsol温度场仿真无法模拟微米级激光光斑