C语言之考勤模拟系统平台(千行代码)

简介: C语言之考勤模拟系统平台(千行代码)

 考勤模拟系统平台目录

第一章软件需求分析... 1

第二章系统结构设计... 3

2.1 系统架构... 3

2.2 系统组件... 3

2.3 系统流程... 3

第三章数据结构设计... 4

第四章模块划分及各模块功能介绍... 6

4.1 用户模块(User Module)... 6

4.2 组模块(Group Module)... 6

4.3 打卡模块(Clockin Module)... 6

4.4 数据管理模块(Data Management Module)... 7

4.5 安全模块(Security Module)... 7

4.6 用户界面模块(User Interface Module)... 8

4.7 辅助功能模块(Utility Module)... 9

第五章流程图... 8

第六章调试与运行结果... 13

第七章设计心得... 16

参考文献... 17

第一章软件需求分析

1.1 项目背景

随着信息技术的快速发展,考勤管理作为组织管理的重要组成部分,需要更加高效、准确的系统来支持。传统的手工考勤方式存在效率低下、容易出错等问题。为了解决这些问题,我们提出了一个考勤模拟系统,旨在通过计算机程序实现自动化的考勤管理。

1.2 系统目标

本系统旨在实现以下目标:

  • 提供一个用户友好的界面,方便用户进行日常的考勤操作。
  • 实现用户登录和注册功能,确保考勤数据的安全性。
  • 支持用户打卡操作,记录用户考勤时间。
  • 允许用户创建和管理考勤组,以适应不同组织的需求。
  • 提供考勤数据的查询和统计功能,方便管理人员进行考勤审核。

1.3 功能需求

1.3.1 用户模块

  • 用户注册:允许新用户创建账户。
  • 用户登录:允许用户通过用户名和密码登录系统。
  • 用户信息管理:允许用户查看和修改个人信息。

1.3.2 组模块

  • 组创建:允许用户创建新的组,并设置组名。
  • 组成员管理:允许管理员邀请新成员加入组,设置成员的优先级。
  • 组成员查看:允许用户查看自己所在的所有组。

1.3.3 打卡模块

  • 打卡记录:允许用户在指定时间内打卡。
  • 打卡数据查看:允许用户查看自己的打卡记录。
  • 打卡事件创建:允许有权限的用户发布新的打卡事件。

1.3.4 数据管理

  • 数据持久化:系统需要将用户数据、组数据和打卡数据存储在文件中。
  • 数据读取:系统启动时需要从文件中读取现有数据。

1.4 性能需求

  • 系统应能够处理至少 MAX_USER 个用户,MAX_GROUP 个组,以及 MAX_CLOCKIN 条打卡记录。
  • 系统应保证数据的一致性和完整性。

1.5 安全需求

  • 用户密码应进行加密存储,保证用户信息安全。
  • 系统应提供基本的权限控制,确保数据访问安全。

1.6 系统环境

  • 系统应在常见的操作系统上运行,如 WindowsLinux 等。
  • 系统应使用标准 C 语言编写,确保良好的兼容性。

1.7 数据结构设计

1.7.1 用户(User

  • 用户IDuid):唯一标识符。
  • 密码(password):登录凭证。

1.7.2 打卡记录(Clockin

  • 开始时间(begin_time):打卡开始的具体时间。
  • 结束时间(end_time):打卡结束的具体时间。
  • 用户打卡状态数组(in):记录哪些用户已打卡。
  • 所属组(group_from):打卡记录所属的组。

第二章系统结构设计

2.1 系统架构

系统采用分层架构,主要分为以下几个层次:

  1. 数据访问层:负责数据的存取,与文件系统交互,实现数据的持久化。
  2. 业务逻辑层:处理具体的业务需求,如用户注册、登录、打卡等。
  3. 表示层:提供用户界面,与用户进行交互,接收用户输入并展示处理结果。

2.2 系统组件

  1. 用户管理组件
  • 负责处理用户的注册、登录和信息管理。
  • 与数据访问层的用户数据存储进行交互。
  1. 组管理组件
  • 允许用户创建组、管理组成员和查看组信息。
  • 与数据访问层的组数据存储进行交互。
  1. 打卡管理组件
  • 处理用户的打卡请求,记录打卡时间。
  • 与数据访问层的打卡数据存储进行交互。
  1. 数据持久化组件
  • 负责将用户数据、组数据和打卡数据存储到文件系统。
  • 在系统启动时从文件中恢复数据。
  1. 安全组件
  • 负责密码加密和权限控制,确保数据安全。

2.3 系统流程

  1. 启动流程
  • 系统启动时,数据持久化组件从文件中加载数据到内存。
  1. 用户交互流程
  • 用户通过表示层与系统交互,输入命令或数据。
  • 表示层将用户请求转发至业务逻辑层。
  • 业务逻辑层处理请求,并与数据访问层交互以执行数据操作。
  1. 数据操作流程
  • 数据访问层执行数据的增删改查操作。
  • 操作结果反馈至业务逻辑层,最终呈现给用户。

第三章数据结构设计

3.1 用户数据结构 (user)

用户数据结构用于存储用户的基本信息,包括用户ID和密码。每个用户在系统中都是唯一的。

typedef struct user {
char uid[30]; // 用户ID,用于唯一标识一个用户
char password[30];// 用户密码,用于登录验证
} user;

image.gif

3.2 组数据结构 (group)

组数据结构用于存储关于考勤组的信息,包括组名、成员列表和成员的优先级。

typedef struct group {
char group_name[100]; // 组名,标识一个考勤组
int member[MAX_USER]; // 成员列表,记录属于该组的用户ID
int priority[MAX_USER]; // 成员优先级,通常管理员的优先级较高
} group;

image.gif

3.3 打卡记录数据结构 (clockin)

打卡记录数据结构用于存储关于打卡事件的详细信息,包括打卡的开始和结束时间,以及哪些用户参与了打卡。

typedef struct clockin {
    time_t begin_time;        // 打卡开始时间
    time_t end_time;          // 打卡结束时间
    int in[MAX_USER];         // 用户打卡状态数组,记录哪些用户已打卡
    int group_from;           // 所属组,标识这个打卡记录属于哪个考勤组
} clockin;

image.gif

3.4 系统级全局变量

系统级全局变量用于维护系统的当前状态和数据集合的规模。

user user_set[MAX_USER];             // 用户集合,存储所有用户的信息
int user_set_length = 0;             // 用户集合的当前大小
group group_set[MAX_GROUP];          // 组集合,存储所有考勤组的信息
int group_set_length = 0;            // 组集合的当前大小
clockin clockin_set[MAX_CLOCKIN];    // 打卡记录集合,存储所有打卡记录
int clockin_set_length = 0;          // 打卡记录集合的当前大小
int current_user = -1;               // 当前登录的用户ID
int global_target_group = -1;         // 全局目标组,用于某些操作中的上下文信息

image.gif

3.5 功能函数

系统还提供了一些功能函数来处理数据集合,例如:

  • search_user(user usr): 在用户集合中搜索特定用户。
  • search_uid(char *uid): 通过用户ID搜索用户。
  • read_user_set() write_user_set(): 从文件读取和写入用户数据集合。
  • read_group_set() write_group_set(): 从文件读取和写入组数据集合。
  • read_clockin_set() write_clockin_set(): 从文件读取和写打卡记录集合。

这些函数实现了数据的持久化和基本的增删查改操作。

第四章模块划分及各模块功能介绍

4.1 用户模块(User Module)

用户模块负责处理与用户相关的所有操作,包括用户注册、登录、信息管理等。

4.1.1 用户注册功能

  • 允许新用户创建账户,输入用户名和密码,并存储到用户数据集中。

4.1.2 用户登录功能

  • 允许用户通过输入用户名和密码登录系统,验证用户凭证。

4.1.3 用户信息管理功能

  • 用户可以查看和修改自己的个人信息,如更改密码等。

4.2 组模块(Group Module)

组模块管理用户的分组信息,包括创建组、管理组成员和查看组信息。

4.2.1 组创建功能

  • 允许用户创建新的组,并设置组名,同时成为该组的管理员。

4.2.2 组成员管理功能

  • 允许管理员邀请新成员加入组,设置成员的优先级(管理员或普通成员)。

4.2.3 组成员查看功能

  • 允许用户查看自己所在的所有组及其成员信息。

4.3 打卡模块(Clockin Module)

打卡模块处理用户的日常打卡操作,包括打卡记录、打卡数据查看和打卡事件创建。

4.3.1 打卡记录功能

  • 允许用户在指定时间内进行打卡操作,记录考勤时间。

4.3.2 打卡数据查看功能

  • 允许用户查看自己的打卡记录,包括打卡时间和打卡状态。

4.3.3 打卡事件创建功能

  • 允许有权限的用户(通常是管理员)发布新的打卡事件,设定打卡的起止时间和参与成员。

4.4 数据管理模块(Data Management Module)

数据管理模块负责系统的数据持久化和读取,确保数据的一致性和完整性。

4.4.1 数据持久化功能

  • 系统需要将用户数据、组数据和打卡数据存储在文件中,保证数据不会因程序关闭而丢失。

4.4.2 数据读取功能

  • 系统启动时需要从文件中读取现有数据,恢复系统状态。

4.5 安全模块(Security Module)

安全模块确保系统的安全性,包括密码加密和权限控制。

4.5.1 密码加密功能

  • 用户密码应进行加密存储,保证用户信息安全。

4.5.2 权限控制功能

  • 系统应提供基本的权限控制,确保用户只能访问授权的数据和功能。

4.6 用户界面模块(User Interface Module)

用户界面模块提供与用户的交互界面,接收用户输入并展示处理结果。

4.6.1 命令行界面

  • 系统通过命令行界面与用户交互,提供清晰的指令和反馈。

4.7 辅助功能模块(Utility Module)

辅助功能模块提供一些辅助性的功能,如搜索、数据验证等。

4.7.1 搜索功能

  • 提供搜索用户、组和打卡记录的功能。

4.7.2 数据验证功能

  • 对用户输入进行验证,确保数据的准确性和有效性。

第五章流程图

5.1整体流程图

image.gif 编辑

5.2用户模块部分流程图

image.gif 编辑

5.3打卡模块部分流程图

image.gif 编辑

5.4组模块部分流程图

image.gif 编辑

5.5数据管理模块部分流程图

image.gif 编辑

 

第六章调试与运行结果

6.1显示目前所有打卡

image.gif 编辑

6.2查看组打卡情况

image.gif 编辑

6.3管理员权限目录

image.gif 编辑

6.4正常打卡目录

image.gif 编辑

6.5打卡时间

image.gif 编辑

6.6显示成员在组的打卡情况

image.gif 编辑

6.7显示组的打卡情况

image.gif 编辑

第七章设计心得

在本章中,我将分享在开发考勤模拟系统过程中的心得体会、遇到的挑战、解决方案以及从中学到的经验。

7.1 项目启动阶段

项目启动初期,需求分析是关键步骤。与团队成员进行多轮讨论,确保对考勤模拟系统的需求有深刻理解。需求分析不仅帮助我们明确了系统目标和功能需求,而且为后续的设计和实现奠定了基础。

7.2 系统设计阶段

系统设计阶段是将需求转化为具体实现的桥梁。在这一阶段,我们采用了分层架构,明确了数据访问层、业务逻辑层和表示层的职责。分层架构的好处在于它提高了代码的可维护性和可扩展性。

7.3 数据结构设计

数据结构的设计是系统设计的核心。我们定义了用户(User)、组(Group)和打卡记录(Clockin)三个主要的数据结构,并在全局变量中维护了这些数据集合的状态。在设计数据结构时,我们注重了数据的一致性和完整性,为后续的数据操作打下了基础。

7.4 模块实现

在模块实现阶段,我们面临了如何高效管理用户、组和打卡数据的挑战。通过实现功能函数如search_userread_user_set等,我们确保了数据操作的便利性和准确性。此外,我们还实现了数据持久化,确保了系统的数据不会因为程序的关闭而丢失。

7.5 用户界面设计

用户界面是用户与系统交互的窗口。我们采用了命令行界面,因为它简单且易于实现。在设计用户界面时,我们注重了用户体验,提供了清晰的指令和反馈,使用户能够轻松地进行考勤操作。

7.6 安全性考虑

安全性是系统设计中不可忽视的一部分。我们意识到用户密码的安全性至关重要,因此在设计安全模块时,我们采用了加密存储密码的策略。此外,我们还实现了基本的权限控制,以确保数据访问的安全性。

7.7 测试与调试

在测试与调试阶段,我们发现并解决了多个问题。通过不断的测试,我们优化了系统的性能,确保了系统的稳定性。调试过程中,我们使用了多种调试工具和技术,以确保及时发现并修复问题。

7.8 项目总结

通过开发考勤模拟系统,我们团队学到了很多宝贵的经验。我们认识到了团队协作的重要性,以及在软件开发过程中持续沟通的必要性。此外,我们也意识到了代码的可读性和可维护性对于长期项目成功的重要性。

7.9 未来展望

考勤模拟系统目前虽然已经实现了基本功能,但仍有改进和扩展的空间。未来,我们计划添加更多的功能,如图形用户界面(GUI)、移动设备兼容性以及更高级的安全特性。

参考文献

C++员工考勤管理系统_c++程序设计课公司员工考勤管理系统-CSDN博客

C++员工管理系统(封装+多态+继承+分类化+函数调用+读写文件+指针+升序降序算法等一系列知识结合) - Bytezero! - 博客园 (cnblogs.com)

C++公司员工考勤管理系统[2023-01-01]_c++实现考勤系统-CSDN博客

simuler/AttendanceSystem: 员工考勤系统(C语言实现) (github.com)

代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
// 定义最大用户数、最大组数和最大打卡记录数
#define MAX_USER 100
#define MAX_GROUP 1000
#define MAX_CLOCKIN 1000
// 打卡记录结构体
typedef struct clockin
{
    time_t begin_time; // 打卡开始时间
    time_t end_time;   // 打卡结束时间
    int in[MAX_USER];  // 用户打卡状态数组
    int group_from;    // 该打卡记录所属的组编号
}clockin;
// 用户组结构体
typedef struct group
{
    char group_name[100];  // 组名
    int member[MAX_USER];  // 组成员数组
    int priority[MAX_USER]; // 用户在组中的优先级或角色
}group;
// 用户信息结构体
typedef struct user
{
    char uid[30];    // 用户ID
    char password[30]; // 用户密码
}user;
// 用户集合数组和长度
user user_set[MAX_USER];
int user_set_length = 0;
// 组集合数组和长度
group group_set[MAX_GROUP];
int group_set_length = 0;
// 打卡记录集合数组和长度
clockin clockin_set[MAX_CLOCKIN];
int clockin_set_length = 0;
// 用户界面功能选择变量
int ui_func;
// 当前登录用户编号和目标组编号
int current_user = -1;
int global_target_group = -1;
// 搜索用户函数
int search_user(user usr)
{
    int i;
    for (i = 0; i < user_set_length; i++)
    {
        if (strcmp(user_set[i].uid, usr.uid) == 0)
        {
            return i;
        }
    }
    return -1;
}
// 根据用户ID搜索用户编号
int search_uid(char *uid)
{
    int i;
    for (i = 0; i < user_set_length; i++)
    {
        if (strcmp(user_set[i].uid, uid) == 0)
        {
            return i;
        }
    }
    return -1;
}
// 读取用户数据函数
void read_user_set()
{
    FILE *userdata = fopen("data/user_data", "r+");
    if (userdata == NULL)
    {
        printf("读取用户数据失败\n");
        return;
    }
    fseek(userdata, 0, SEEK_END);
    if (ftell(userdata) == 0)           // 空文件
    {
        return;
    }
    fseek(userdata, 0, SEEK_SET);
    fscanf(userdata, "%d", &user_set_length);
    for (int i = 0 ; i < user_set_length; i++)
    {
        fscanf(userdata, "%s", user_set[i].uid);
        fscanf(userdata, "%s", user_set[i].password);
    }
    fclose(userdata);
    return;
}
// 写入用户数据函数
void write_user_set()
{
    FILE *userdata = fopen("data/user_data", "w");
    if (userdata == NULL)
    {
        printf("读取用户数据失败\n");
        return;
    }
    fprintf(userdata, "%d\n", user_set_length);
    for (int i = 0 ; i < user_set_length; i++)
    {
        fprintf(userdata, "%s\n", user_set[i].uid);
        fprintf(userdata, "%s\n", user_set[i].password);
    }
    fclose(userdata);
    return;
}
// 读取组数据函数
void read_group_set()
{
    FILE *groupdata = fopen("data/group_data", "r+");
    if (groupdata == NULL)
    {
        printf("读取组数据失败\n");
        return;
    }
    fseek(groupdata, 0, SEEK_END);
    if (ftell(groupdata) == 0)           // 空文件
    {
        return;
    }
    fseek(groupdata, 0, SEEK_SET);
    fscanf(groupdata, "%d", &group_set_length);
    for (int j = 0; j < group_set_length; j++)
    {
        char temp_str[110];
        fscanf(groupdata, "%s", &temp_str);
        strcpy(group_set[j].group_name, temp_str);
        fscanf(groupdata, "%s", &temp_str);
        for (int i = 0 ; i < MAX_USER; i++)
        {
            group_set[j].member[i] = temp_str[i] - 48;
        }
        fscanf(groupdata, "%s", &temp_str);
        for (int i = 0 ; i < MAX_USER; i++)
        {
            group_set[j].priority[i] = temp_str[i] - 48;
        }
    }
    fclose(groupdata);
    return;
}
// 写入组数据函数
void write_group_set()
{
    FILE *groupdata = fopen("data/group_data", "w");
    if (groupdata == NULL)
    {
        printf("读取组数据失败\n");
        return;
    }
    fprintf(groupdata, "%d\n", group_set_length);
    for (int i = 0 ; i < group_set_length; i++)
    {
        fprintf(groupdata, "%s\n", group_set[i].group_name);
        for (int j = 0; j < MAX_USER; j++)
        {
            fprintf(groupdata, "%d", group_set[i].member[j]);
        }
        fprintf(groupdata, "\n");
        for (int j = 0; j < MAX_USER; j++)
        {
            fprintf(groupdata, "%d", group_set[i].priority[j]);
        }
        fprintf(groupdata, "\n");
    }
    fclose(groupdata);
    return;
}
// 检查用户是否在组中
int is_usr_in_group(int groupNo, int usr)
{
    return group_set[groupNo].member[usr];
}
// 检查打卡记录是否在组中
int is_clockin_in_group(int groupNo, int clockinNo)
{
    return clockin_set[clockinNo].group_from == groupNo;
}
// 用户ID转换为用户编号
int uid_2_usr(char *uid)
{
    for (int i = 0; i < MAX_USER; i++)
    {
        if (strcmp(user_set[i].uid, uid) == 0)
        {
            return i;
        }
    }
    return -1;
}
// 读取打卡记录数据函数
void read_clockin_set()
{
    FILE *clockindata = fopen("data/clockin_data", "r+");
    if (clockindata == NULL)
    {
        printf("读取打卡数据失败\n");
        return;
    }
    for (int i = 0; i < MAX_CLOCKIN; i++)
    {
        clockin_set[i].group_from = -1;
    }
    fseek(clockindata, 0, SEEK_END);
    if (ftell(clockindata) == 0)           // 空文件
    {
        return;
    }
    fseek(clockindata, 0, SEEK_SET);
    fscanf(clockindata, "%d", &clockin_set_length);
    for (int j = 0; j < clockin_set_length; j++)
    {
        char temp_str[110];
        long temp_long;
        int temp_int;
        fscanf(clockindata, "%ld", &temp_long);
        clockin_set[j].begin_time = temp_long;
        fscanf(clockindata, "%ld", &temp_long);
        clockin_set[j].end_time = temp_long;
        fscanf(clockindata, "%s", &temp_str);
        for (int i = 0 ; i < MAX_USER; i++)
        {
            clockin_set[j].in[i] = temp_str[i] - 48;
        }
        fscanf(clockindata, "%d", &temp_int);
        clockin_set[j].group_from = temp_int;
    }
    fclose(clockindata);
    return;
}
// 写入打卡记录数据函数
void write_clockin_set()
{
    FILE *clockindata = fopen("data/clockin_data", "w");
    if (clockindata == NULL)
    {
        printf("读取打卡数据失败\n");
        return;
    }
    fprintf(clockindata, "%d\n", clockin_set_length);
    for (int i = 0 ; i < clockin_set_length; i++)
    {
        fprintf(clockindata, "%ld\n", clockin_set[i].begin_time);
        fprintf(clockindata, "%ld\n", clockin_set[i].end_time);
        for (int j = 0; j < MAX_USER; j++)
        {
            fprintf(clockindata, "%d", clockin_set[i].in[j]);
        }
        fprintf(clockindata, "\n");
        fprintf(clockindata, "%d\n", clockin_set[i].group_from);
    }
    fclose(clockindata);
    return;
}
// 检查用户是否在打卡记录中
int is_usr_in_clockin(int clockinNo)
{
    return group_set[clockin_set[clockinNo].group_from].member[current_user];
}
int main()
{
    ui_func = -1;
    // -2 -- welcome已登录
    // -1 -- welcome未登录
    // 0 -- 登录界面
    // 1 -- 注册界面
    read_user_set();
    read_group_set();
    read_clockin_set();
    while (1)
    {
        system("cls");
        if (ui_func == 0)           // 登录界面
        {
            user login_user;
            printf("请先登录\n用户名:");
            scanf("%s", login_user.uid);
            printf("密码:");
            scanf("%s", login_user.password);
            fflush(stdin);
            if (search_user(login_user) == -1)  // 未注册
            {
                printf("未找到该用户,是否注册?(y/n)\n");
                int temp_i = 1;
                char temp_c;
                while (temp_i)
                {
                    system("cls");
                    printf("未找到该用户,是否注册?(y/n)\n");
                    scanf("%c", &temp_c);
                    fflush(stdin);
                    if (temp_c == 'y' || temp_c == 'n')
                        break;
                }
                if (temp_c == 'y')
                {
                    ui_func = 1;
                    continue;
                }
                else if (temp_c == 'n')
                {
                    ui_func = -1;
                    continue;
                }
            }
            else
            {
                int No = search_user(login_user);
                if (strcmp(login_user.password, user_set[No].password) == 0)
                {
                    printf("登录成功\n");
                    current_user = No;
                    ui_func = -2;
                }
                else
                {
                    printf("密码错误\n");
                    getchar();
                }
            }
        }
        else if (ui_func == 1)          // 注册界面
        {
            user register_user;
            char re_password[30];
            printf("请先注册\n用户名:");
            scanf("%s", register_user.uid);
            printf("密码:");
            scanf("%s", register_user.password);
            printf("请重复密码:");
            scanf("%s", &re_password);
            fflush(stdin);
            if (search_user(register_user) != -1)
            {
                int temp_i = 1;
                char temp_c;
                while (temp_i)
                {
                    system("cls");
                    printf("该用户已存在,是否跳转到登录?(y/n)\n");
                    scanf("%c", &temp_c);
                    fflush(stdin);
                    if (temp_c == 'y' || temp_c == 'n')
                        break;
                }
                if (temp_c == 'y')
                {
                    ui_func = 0;
                    continue;
                }
                else if (temp_c == 'n')
                {
                    ui_func = -1;
                    continue;
                }
            }
            if (strcmp(re_password, register_user.password) != 0)
            {
                printf("两次密码不相同,请再次输入\n");
                ui_func = 1;
                continue;
            }
            else       
            {
                printf("注册成功,将自动为您登录\n");
                strcpy(user_set[user_set_length].uid, register_user.uid);
                strcpy(user_set[user_set_length].password, register_user.password);
                user_set_length++;
                write_user_set();
                current_user = user_set_length - 1;
                ui_func = -2;
            }
        }
        else if (ui_func == -1)         // welcome未登录
        {          
            char temp_c;
            while (1)
            {
                system("cls");
                printf("这是一句welcome\n输入序号以访问功能\n1 登录\n2 注册\n");
                scanf("%c", &temp_c);
                fflush(stdin);
                if (temp_c == '1' || temp_c == '2')
                    break;
            }
            if (temp_c == '1')
                ui_func = 0;
            else
                ui_func = 1;
        }
        else if (ui_func == -2)         // welcome已登录
        {
            int temp_i;
            while (1)
            {
                system("cls");
                printf("你好%s\n输入序号以访问功能\n1 打卡\n2 发布新的打卡\n3 查看我所在的组\n4 创建组\n5 管理组\n9 退出登录\n", user_set[current_user].uid);  
                scanf("%d", &temp_i);
                fflush(stdin);
                if ((temp_i >= 1 && temp_i <= 5) || temp_i == 9)
                    break;
            }
            if (temp_i == 1)
                ui_func = 20;
            else if (temp_i == 4)
                ui_func = 10;
            else if (temp_i == 3)
                ui_func = 11;
            else if (temp_i == 2)
                ui_func = 21;
            else if (temp_i == 9)
                ui_func = 99;
            else if (temp_i == 5)
                ui_func = 30;
        }
        else if (ui_func == 10)        // 创建组
        {
            const char end_str[10] = "$end";
            char temp_uid[30];
            char temp_group_name[100];
            group_set[group_set_length].member[current_user] = 1;
            group_set[group_set_length].priority[current_user] = 1;
            system("cls");
            printf("请输入小组名称:"); 
            scanf("%s", &temp_group_name); 
            strcpy(group_set[group_set_length].group_name, temp_group_name);
            while (1)
            {
                system("cls");
                printf("小组名称:%s\n", group_set[group_set_length].group_name);  
                printf("请输入其它用户的用户名进行邀请\n管理员:%s\n", user_set[current_user].uid);  
                printf("用户:");
                for (int i = 0; i < MAX_USER; i++)
                {
                    if (group_set[group_set_length].member[i] && i != current_user)
                    {
                        printf("%s  ", user_set[i].uid);
                    }
                }
                printf("\n\n其它用户的用户名(或输入%cend结束):", 36);
                scanf("%s", &temp_uid);
                fflush(stdin);
                if (strcmp(end_str, temp_uid) == 0)
                    break;
                if (search_uid(temp_uid) == -1)
                {
                    printf("未找到该用户(按下回车以继续)");
                    getchar();
                }
                else
                {
                    group_set[group_set_length].member[search_uid(temp_uid)] = 1;
                    group_set[group_set_length].priority[search_uid(temp_uid)] = 0;
                }
            }
            system("cls");
            printf("小组创建完毕\n小组名称:%s\n管理员:%s\n", group_set[group_set_length].group_name, user_set[current_user].uid);  
            printf("用户:");
            for (int i = 0; i < MAX_USER; i++)
            {
                if (group_set[group_set_length].member[i] && i != current_user)
                {
                    printf("%s  ", user_set[i].uid);
                }
            }
            printf("\n");
            group_set_length++;
            write_group_set();
            ui_func = -2;
            printf("按下回车以返回主界面\n");
            getchar();
        }
        else if (ui_func == 11)
        {
            system("cls");  
            printf("%s所在的所有组:\n", user_set[current_user].uid);  
            for (int i = 0; i < MAX_GROUP; i++)
            {
                if (is_usr_in_group(i, current_user))
                {
                    printf("%s\n", group_set[i].group_name);  
                }
            }
            ui_func = -2;
            printf("\n按下回车以返回主界面\n");
            getchar();
        }
        else if (ui_func == 20)
        {
            system("cls");  
            printf("%s目前有的所有打卡:\n", user_set[current_user].uid);  
            for (int i = 0; i < MAX_CLOCKIN; i++)
            {
                if (group_set[clockin_set[i].group_from].member[current_user])
                {
                    struct tm *showtime;
                    printf("打卡编号:%d\n", i);
                    showtime = localtime(&clockin_set[i].begin_time);
                    printf("起始:%s", asctime(showtime));
                    showtime = localtime(&clockin_set[i].end_time);
                    printf("结束:%s", asctime(showtime));
                    if (clockin_set[i].in[current_user] == 1)
                    {
                        printf("已打卡\n\n");
                    }
                    else
                    {
                        printf("未打卡\n\n");
                    } 
                }
            }
            int target_clockin = -2;
            printf("输入打卡编号进行打卡(或输入-1返回主界面)\n");
            scanf("%d", &target_clockin);
            fflush(stdin);
            if (target_clockin == -1 || is_usr_in_clockin(target_clockin))
            {
                if (target_clockin == -1)
                {
                    ui_func = -2;
                    continue;
                }
                else if (clockin_set[target_clockin].in[current_user] == 1)
                {
                    printf("已打卡,请勿重复打卡。\n");
                    getchar();
                    continue;
                }
                else
                {
                    time_t now_time = time(0);
                    time(&now_time);
                    if (now_time >= clockin_set[target_clockin].begin_time && now_time <= clockin_set[target_clockin].end_time)
                    {
                        printf("打卡成功。\n");
                        getchar();
                        clockin_set[target_clockin].in[current_user] = 1;
                        write_clockin_set();
                        continue;
                    }
                    else
                    {
                        printf("打卡失败。未在指定时间\n");
                        getchar();
                        continue;
                    }
                }
            }
            else
            {
                printf("输入有误,请重新输入\n");
                getchar();
            }
        }
        else if (ui_func == 21)
        {
            system("cls");  
            int have_any_p = 0;
            for (int i = 0; i < MAX_GROUP; i++)
            {
                if (is_usr_in_group(i, current_user))
                {
                    if (group_set[i].priority[current_user])
                        have_any_p = 1; 
                }
            }
            if (have_any_p == 0)
            {
                ui_func = -2;
                printf("你目前没有任何权限,即将返回\n");
                getchar();
                continue;
            }
            printf("%s所有有权限的组:\n", user_set[current_user].uid);  
            for (int i = 0; i < MAX_GROUP; i++)
            {
                if (is_usr_in_group(i, current_user))
                {
                    if (group_set[i].priority[current_user])
                        printf("%s\n", group_set[i].group_name);  
                }
            }
            printf("\n输入选择要创建打卡的组的名称:");
            char temp_gn[100];
            scanf("%s", &temp_gn);
            fflush(stdin);
            int target_group = 0;
            int flag = 0;
            for (; target_group < MAX_GROUP && flag == 0; target_group++)
            {
                if (is_usr_in_group(target_group, current_user))
                {
                    if (group_set[target_group].priority[current_user])
                    {
                        if (strcmp(temp_gn, group_set[target_group].group_name) == 0)
                        {
                            flag = 1;
                            break;
                        }
                    }
                }
            }
            if (flag == 0)
            {
                printf("\n未找到该组,请重新输入\n");
                getchar();
                continue;
            }
            else
            {
                clockin_set[clockin_set_length].group_from = target_group;
                
                int holding = 0;            // 分钟
                time_t begin = time(0);
                time_t end = time(0);
                struct tm *time_show;
                time(&begin);
                system("cls"); 
                printf("请输入打卡持续时间(分钟):");
                scanf("%d", &holding);
                fflush(stdin);
                end = begin + holding * 60;
                printf("小组:%s\n", group_set[target_group].group_name);
                time_show = localtime(&begin);
                printf("起始时间:%s", asctime(time_show));
                time_show = localtime(&end);
                printf("结束时间:%s", asctime(time_show));
                clockin_set[clockin_set_length].begin_time = begin;
                clockin_set[clockin_set_length].end_time = end;
                for (int i = 0; i < MAX_USER; i++)
                {
                    clockin_set[clockin_set_length].in[i] = 0;
                }
                clockin_set_length++;
                write_clockin_set();
                ui_func = -2;
                printf("\n打卡创建完毕,回车以返回主界面\n");
                getchar();
            }
            
        }
        else if (ui_func == 99)
        {
            ui_func = -1;
            current_user = -1;
            printf("已退出登录,将返回登录界面\n");
            getchar();
        }
        else if (ui_func == 30)
        {
            system("cls"); 
            printf("%s所在的所有组:\n", user_set[current_user].uid);  
            for (int i = 0; i < MAX_GROUP; i++)
            {
                if (is_usr_in_group(i, current_user))
                {
                    printf("%s\n", group_set[i].group_name);  
                }
            }
            printf("\n输入选择要查看的组的名称(输入$back返回):");
            char temp_gn[100];
            scanf("%s", &temp_gn);
            fflush(stdin);
            if (strcmp("$back", temp_gn) == 0)
            {
                ui_func = -2;
                continue;
            }
            int target_group = 0;
            int flag = 0;
            for (; target_group < MAX_GROUP && flag == 0; target_group++)
            {
                if (is_usr_in_group(target_group, current_user))
                {
                    if (strcmp(temp_gn, group_set[target_group].group_name) == 0)
                    {
                        flag = 1;
                        break;
                    }
                }
            }
            if (flag == 0)
            {
                printf("\n未找到该组,请重新输入\n");
                getchar();
                continue;
            }
            else
            {
                system("cls"); 
                printf("小组:%s\n", group_set[target_group].group_name);
                printf("管理员:");
                for (int i = 0; i < MAX_USER; i++)
                {
                    if (group_set[target_group].member[i] && group_set[target_group].priority[i])
                    {
                        printf("%s  ", user_set[i].uid);
                    }
                }
                printf("\n");
                printf("其它成员:");
                for (int i = 0; i < MAX_USER; i++)
                {
                    if (group_set[target_group].member[i] && group_set[target_group].priority[i] == 0)
                    {
                        printf("%s  ", user_set[i].uid);
                    }
                }
                printf("\n");
                if (group_set[target_group].priority[current_user])
                {
                    ui_func = 31;
                    global_target_group = target_group;
                    continue;
                }
                else
                {
                    printf("您是一般成员\n(回车以返回)");
                    getchar();
                }
            }
        }
        else if (ui_func == 31)
        {
            int temp_i;
            while (1)
            {
                system("cls");
                printf("小组:%s\n", group_set[global_target_group].group_name);
                printf("管理员:");
                for (int i = 0; i < MAX_USER; i++)
                {
                    if (group_set[global_target_group].member[i] && group_set[global_target_group].priority[i])
                    {
                        printf("%s  ", user_set[i].uid);
                    }
                }
                printf("\n");
                printf("其它成员:");
                for (int i = 0; i < MAX_USER; i++)
                {
                    if (group_set[global_target_group].member[i] && group_set[global_target_group].priority[i] == 0)
                    {
                        printf("%s  ", user_set[i].uid);
                    }
                }
                printf("\n您是管理员\n输入序号以访问功能\n1 查看个人数据\n2 查看打卡数据\n9 返回\n");
                scanf("%d", &temp_i);
                fflush(stdin);
                if ((temp_i >= 1 && temp_i <= 2) || temp_i == 9)
                    break;
            }
            if (temp_i == 1)
            {
                char temp_uid[30];
                while (1)
                {
                    system("cls");
                    printf("小组:%s\n", group_set[global_target_group].group_name);
                    printf("全部成员:");
                    for (int i = 0; i < MAX_USER; i++)
                    {
                        if (group_set[global_target_group].member[i])
                        {
                            printf("%s  ", user_set[i].uid);
                        }
                    }
                    printf("\n输入成员的uid以查看其打卡数据\n");
                    scanf("%s", &temp_uid);
                    fflush(stdin);
                    if (is_usr_in_group(global_target_group, uid_2_usr(temp_uid)))
                    {
                        break;
                    }
                    else
                    {
                        printf("\n该成员不在小组中\n");
                        getchar();
                    }
                }
                system("cls");  
                printf("成员:%s目前在组内所有打卡:\n", user_set[uid_2_usr(temp_uid)].uid);  
                int all = 0, intime = 0, outtime = 0;
                for (int i = 0; i < MAX_CLOCKIN; i++)
                {
                    if (group_set[clockin_set[i].group_from].member[uid_2_usr(temp_uid)] && clockin_set[i].group_from == global_target_group)
                    {
                        all++;
                        struct tm *showtime;
                        printf("打卡编号:%d\n", i);
                        showtime = localtime(&clockin_set[i].begin_time);
                        printf("起始:%s", asctime(showtime));
                        showtime = localtime(&clockin_set[i].end_time);
                        printf("结束:%s", asctime(showtime));
                        if (clockin_set[i].in[uid_2_usr(temp_uid)] == 1)
                        {
                            printf("已打卡\n\n");
                            intime++;
                        }
                        else
                        {
                            printf("未打卡\n\n");
                            outtime++;
                        } 
                    }
                }
                printf("\n总打卡%d次,准时%d次,迟到%d次,到勤率%.2lf\n", all, intime, outtime, (double)intime/(double)all);
                getchar();
                continue;
            }
            else if (temp_i == 2)
            {
                int temp_int;
                while (1)
                {
                    system("cls");
                    printf("小组:%s\n", group_set[global_target_group].group_name);
                    printf("全部打卡:\n");
                    for (int i = 0; i < clockin_set_length; i++)
                    {
                        if (clockin_set[i].group_from == global_target_group)
                        {
                            struct tm *showtime;
                            printf("打卡编号:%d\n", i);
                            showtime = localtime(&clockin_set[i].begin_time);
                            printf("起始:%s", asctime(showtime));
                            showtime = localtime(&clockin_set[i].end_time);
                            printf("结束:%s", asctime(showtime));
                        }
                    }
                    printf("\n输入打卡的编号以查看其打卡数据\n");
                    scanf("%d", &temp_int);
                    fflush(stdin);
                    if (is_clockin_in_group(global_target_group, temp_int))
                    {
                        break;
                    }
                    else
                    {
                        printf("\n小组中没有该打卡\n");
                        getchar();
                    }
                }
                struct tm *showtime;
                system("cls");
                printf("打卡编号:%d\n", temp_int);
                showtime = localtime(&clockin_set[temp_int].begin_time);
                printf("起始:%s", asctime(showtime));
                showtime = localtime(&clockin_set[temp_int].end_time);
                printf("结束:%s", asctime(showtime));
                int all = 0, intime = 0, outtime = 0;
                printf("已签到:\n");
                for (int i = 0; i < MAX_USER; i++)
                {
                    if (group_set[global_target_group].member[i])
                    {
                        all++;
                        if (clockin_set[temp_int].in[i])
                        {
                            intime++;
                            printf("%s  ", user_set[i].uid);
                        }
                    }
                }
                printf("\n未签到:\n");
                for (int i = 0; i < MAX_USER; i++)
                {
                    if (group_set[global_target_group].member[i])
                    {
                        if (clockin_set[temp_int].in[i] == 0)
                        {
                            outtime++;
                            printf("%s  ", user_set[i].uid);
                        }
                    }
                }
                printf("\n总共%d人参与打卡,准时%d人,迟到%d人,到勤率%.2lf\n", all, intime, outtime, (double)intime/(double)all);
            }
            else
            {
                global_target_group = -1;
                ui_func = -2;
                continue;
            }
            getchar();
        }
    }
}

image.gif


相关文章
|
10天前
|
存储 人工智能 弹性计算
阿里云弹性计算_加速计算专场精华概览 | 2024云栖大会回顾
2024年9月19-21日,2024云栖大会在杭州云栖小镇举行,阿里云智能集团资深技术专家、异构计算产品技术负责人王超等多位产品、技术专家,共同带来了题为《AI Infra的前沿技术与应用实践》的专场session。本次专场重点介绍了阿里云AI Infra 产品架构与技术能力,及用户如何使用阿里云灵骏产品进行AI大模型开发、训练和应用。围绕当下大模型训练和推理的技术难点,专家们分享了如何在阿里云上实现稳定、高效、经济的大模型训练,并通过多个客户案例展示了云上大模型训练的显著优势。
|
14天前
|
存储 人工智能 调度
阿里云吴结生:高性能计算持续创新,响应数据+AI时代的多元化负载需求
在数字化转型的大潮中,每家公司都在积极探索如何利用数据驱动业务增长,而AI技术的快速发展更是加速了这一进程。
|
5天前
|
并行计算 前端开发 物联网
全网首发!真·从0到1!万字长文带你入门Qwen2.5-Coder——介绍、体验、本地部署及简单微调
2024年11月12日,阿里云通义大模型团队正式开源通义千问代码模型全系列,包括6款Qwen2.5-Coder模型,每个规模包含Base和Instruct两个版本。其中32B尺寸的旗舰代码模型在多项基准评测中取得开源最佳成绩,成为全球最强开源代码模型,多项关键能力超越GPT-4o。Qwen2.5-Coder具备强大、多样和实用等优点,通过持续训练,结合源代码、文本代码混合数据及合成数据,显著提升了代码生成、推理和修复等核心任务的性能。此外,该模型还支持多种编程语言,并在人类偏好对齐方面表现出色。本文为周周的奇妙编程原创,阿里云社区首发,未经同意不得转载。
|
11天前
|
人工智能 运维 双11
2024阿里云双十一云资源购买指南(纯客观,无广)
2024年双十一,阿里云推出多项重磅优惠,特别针对新迁入云的企业和初创公司提供丰厚补贴。其中,36元一年的轻量应用服务器、1.95元/小时的16核60GB A10卡以及1元购域名等产品尤为值得关注。这些产品不仅价格亲民,还提供了丰富的功能和服务,非常适合个人开发者、学生及中小企业快速上手和部署应用。
|
6天前
|
人工智能 自然语言处理 前端开发
用通义灵码,从 0 开始打造一个完整APP,无需编程经验就可以完成
通义灵码携手科技博主@玺哥超carry 打造全网第一个完整的、面向普通人的自然语言编程教程。完全使用 AI,再配合简单易懂的方法,只要你会打字,就能真正做出一个完整的应用。本教程完全免费,而且为大家准备了 100 个降噪蓝牙耳机,送给前 100 个完成的粉丝。获奖的方式非常简单,只要你跟着教程完成第一课的内容就能获得。
|
21天前
|
自然语言处理 数据可视化 前端开发
从数据提取到管理:合合信息的智能文档处理全方位解析【合合信息智能文档处理百宝箱】
合合信息的智能文档处理“百宝箱”涵盖文档解析、向量化模型、测评工具等,解决了复杂文档解析、大模型问答幻觉、文档解析效果评估、知识库搭建、多语言文档翻译等问题。通过可视化解析工具 TextIn ParseX、向量化模型 acge-embedding 和文档解析测评工具 markdown_tester,百宝箱提升了文档处理的效率和精确度,适用于多种文档格式和语言环境,助力企业实现高效的信息管理和业务支持。
3960 5
从数据提取到管理:合合信息的智能文档处理全方位解析【合合信息智能文档处理百宝箱】
|
10天前
|
算法 安全 网络安全
阿里云SSL证书双11精选,WoSign SSL国产证书优惠
2024阿里云11.11金秋云创季活动火热进行中,活动月期间(2024年11月01日至11月30日)通过折扣、叠加优惠券等多种方式,阿里云WoSign SSL证书实现优惠价格新低,DV SSL证书220元/年起,助力中小企业轻松实现HTTPS加密,保障数据传输安全。
533 3
阿里云SSL证书双11精选,WoSign SSL国产证书优惠
|
9天前
|
数据采集 人工智能 API
Qwen2.5-Coder深夜开源炸场,Prompt编程的时代来了!
通义千问团队开源「强大」、「多样」、「实用」的 Qwen2.5-Coder 全系列,致力于持续推动 Open Code LLMs 的发展。
|
17天前
|
安全 数据建模 网络安全
2024阿里云双11,WoSign SSL证书优惠券使用攻略
2024阿里云“11.11金秋云创季”活动主会场,阿里云用户通过完成个人或企业实名认证,可以领取不同额度的满减优惠券,叠加折扣优惠。用户购买WoSign SSL证书,如何叠加才能更加优惠呢?
998 3
|
14天前
|
机器学习/深度学习 存储 人工智能
白话文讲解大模型| Attention is all you need
本文档旨在详细阐述当前主流的大模型技术架构如Transformer架构。我们将从技术概述、架构介绍到具体模型实现等多个角度进行讲解。通过本文档,我们期望为读者提供一个全面的理解,帮助大家掌握大模型的工作原理,增强与客户沟通的技术基础。本文档适合对大模型感兴趣的人员阅读。
453 18
白话文讲解大模型| Attention is all you need