lls696 2023-03-23 14:52 采纳率: 100%
浏览 165
已结题

C语言程序设计中链表问题

程序设计我想做一个学生考勤系统

img


此为结构体要素(几乎大部分功能函数无误可忽略)

img

img

此为读文件代码

img


img


此为终端输出和保存数据代码

运行后输入5 会出现一行无学生信息的文字

img

后输入1 添加一名学生信息

img

后输入5 再次查看 信息已输入但是无信息文字还在

img

随后输入8保存后输入9退出 查看文本 文本中存在刚刚输入的一项信息

img

后再次打开程序 输入5查看 原本发现无信息文字被所输入信息填满 即第一条输入的学生信息会重复两次

img


后续大量数据发现 只有第一个输入的学生信息会被重复两遍 其余功能均正常使用 而在show函数中多添加一个pr=pr->next就能只输出一个首位学生信息
本人 感觉问题会不会feof()导致多读一行重复了
求帮忙看看 以及怎么修改 以下是源码

#include"Attendance system.h";
int sum1 = 0, sum2 = 0, sum3 = 0;

char xuehao[100];//学号
char name[100];//姓名
char banji[100];//班级
char data[100];//时间
char daoke[10];//到课情况
char num[100][30];//存储一共有多少学号
char num2[100][30];//存储一共有多少姓名以便后面排序使用
char num3[100][30];//存储时间

void creatnewnode(node*& student)
{
    student = (node*)malloc(sizeof(node));
    student->next = NULL;
}

void insert(node*& L, node* p)
{
    node* q = NULL;
    q = L;
    p->next = q->next;
    q->next = p;
}

void read(node* L)
{
    FILE* FP;
    FP = fopen("data.txt", "rb");
    if (FP == NULL)
    {
        printf("该文件不存在!");
        exit(0);//终止程序 
    }
    while (!feof(FP))
    {
        node* pr = L;
        node* p=NULL;
        node* l = (node*)malloc(sizeof(node));//创建节点中转信息
        fscanf(FP, "%s%s%s%s%s", xuehao, name, banji, data, daoke);
        strcpy(l->data.xuehao, xuehao);
        strcpy(l->data.name, name);
        strcpy(l->data.banji, banji);
        strcpy(l->data.data, data);
        strcpy(l->data.daoke, daoke);
        int flag = 1, flag2 = 1, flag3 = 1;
        for (int i = 0; i <= sum1; i++)
        {
            if (strcmp(num[i], xuehao) == 0)
            {
                flag = 0;
            }
        }
        if (flag)
        {
            strcpy(num[sum1], xuehao);
            sum1++;
        }
        for (int i = 0; i <= sum2; i++)
        {
            if (strcmp(num2[i], name) == 0)
            {
                flag2 = 0;
            }
        }
        if (flag2)
        {
            strcpy(num2[sum2], name);
            sum2++;
        }
        for (int i = 0; i <= sum3; i++)
        {
            if (strcmp(num3[i], data) == 0)
            {
                flag3 = 0;
            }
        }
        if (flag3)
        {
            strcpy(num3[sum3], data);
            sum3++;
        }
        insert(L, l);
        l = l->next;
    }
    fclose(FP);

}

void search(node* student) 
{
    node* pr = student->next;
    printf("输入1按学号查询,输入2按姓名查询,输入3按考勤时间查询:");
    int flag;
    scanf("%d", &flag);
    if (flag == 1)
    {
        int flag2 = 1;
        pr = student->next;
        printf("请输入学号:");
        scanf("%s", xuehao);
        while (pr != NULL) 
        {
            if (strcmp(pr->data.xuehao, xuehao) == 0)
            {
                flag2 = 0;
                printf("学号:%s  ", pr->data.xuehao);
                printf("姓名:%s  ", pr->data.name);
                printf("时间:%s  到课状态:%s\n", pr->data.data, pr->data.daoke);
            }
            pr = pr->next;
        }
        if (flag2)
        {
            printf("学号不存在!\n");
        }
    }
    else if (flag == 2) //按姓名查询
    {
        pr = student->next;
        printf("请输入姓名:");
        scanf("%s", name);
        while (pr != NULL)
        {
            if (strcmp(pr->data.name, name) == 0)
            {
                printf("学号:%s\n", pr->data.xuehao);
                printf("姓名:%s\n", pr->data.name);
                printf("时间:%s  到课状态:%s", pr->data.data, pr->data.daoke);
            }
            pr = pr->next;
        }
        if (pr == NULL)
        {
            printf("姓名不存在!\n");
        }
    }
    else if(flag==3)  //按时间查询
    {
        pr = student->next;
        printf("(注意!请严格按照00月00日00点00分输入)请输入具体时间:");
        scanf("%s", data);
        while (pr != NULL)
        {
            if (strcmp(pr->data.data, data) == 0) 
            {
                printf("学号:%s\n", pr->data.xuehao);
                printf("姓名:%s\n", pr->data.name);
                printf("时间:%s  到课状态:%s", pr->data.data, pr->data.daoke);
            }
            pr = pr->next;
        }
        if (pr == NULL)
        {
            printf("该时间不存在记录!\n");
        }
    }
}

void add(node* L) 
{
    printf("请输入你想新增信息的学生学号:");
    scanf("%s",xuehao);
    printf("请输入你想新增信息的学生姓名:");
    scanf("%s", name);
    printf("(注意!请严格按照00月00日00点00分输入)请输入到课时间:");
    scanf("%s", data);
    printf("请输入学生班级:");
    scanf("%s", banji);
    node* pr = L->next;
    while (pr != NULL)
    {
        if (strcmp(pr->data.xuehao, xuehao)==0)
        {
            if (strcmp(pr->data.data, data) == 0) 
            {
                printf("该学生在该时间的考勤信息已存在!!");
                break;
            }
        }
        pr = pr->next;
    }
    if (pr == NULL) 
    {
        node* p;
        creatnewnode(p);
        strcpy(p->data.xuehao, xuehao);
        strcpy(p->data.name, name);
        strcpy(p->data.data, data);
        strcpy(p->data.banji, banji);
        printf("注意1为到课  2为旷课  3为事假  4为病假  5为迟到  6为早退\n");
        printf("请输入该时间的到课情况:");
        scanf("%s", daoke);
        strcpy(p->data.daoke,daoke);
        int flag = 1, flag2 = 1, flag3 = 1;
        for (int i = 0; i <= sum1; i++)
        {
            if (strcmp(num[i], xuehao) == 0)
            {
                flag = 0;
            }
        }
        if (flag)
        {
            strcpy(num[sum1], xuehao);
            sum1++;
        }
        for (int i = 0; i <= sum2; i++)
        {
            if (strcmp(num2[i], name) == 0)
            {
                flag2 = 0;
            }
        }
        if (flag2)
        {
            strcpy(num2[sum2], name);
            sum2++;
        }
        for (int i = 0; i <= sum3; i++)
        {
            if (strcmp(num3[i], data) == 0)
            {
                flag3 = 0;
            }
        }
        if (flag3)
        {
            strcpy(num3[sum3], data);
            sum3++;
        }
        insert(L, p);
        printf("添加成功!\n");
    }
}

void modify(node* L)
{
    node* pr = L->next;
    printf("请输入你想要修改的学生学号:");
    scanf("%s", xuehao);
    printf("请输入你想修改学生记录的具体时间:");
    scanf("%s", data);
    while (pr != NULL)
    {
        if(strcmp(pr->data.xuehao, xuehao) == 0)
        {
            if (strcmp(pr->data.data, data) == 0)
            {
                printf("注意1为到课  2为旷课  3为事假  4为病假  5为迟到  6为早退\n");
                printf("请输入学生到课情况:");
                scanf("%s", daoke);
                strcpy(pr->data.daoke, daoke);
                printf("修改成功!\n");
                break;
            }
        }
        pr = pr->next;
    }
    if (pr == NULL)
    {
        printf("无该日学生信息!");
    }
}

void del(node* L)
{
    node* pr = L->next;
    node* p = L;
    if (L->next == NULL)
    {
        printf("无考勤信息,请先添加");
        return;
    }
    printf("请输入你想要删除的学生记录的学生学号:");
    scanf("%s", xuehao);
    printf("请输入你想要删除的学生记录的具体时间:");
    scanf("%s", data);
    int flag = 1;
    while (pr != NULL)
    {
        if (strcmp(pr->data.xuehao, xuehao) == 0)
        {
            if (strcmp(pr->data.data, data) == 0)
            {
                flag = 0;
                p->next = pr->next;
                free(pr);
                node* p = L->next;
                int t = 0, k = 0;
                while (p != NULL)
                {
                    if (strcmp(p->data.xuehao, xuehao) == 0)
                    {
                        t++;
                    }
                    if (strcmp(p->data.data, data) == 0)
                    {
                        k++;
                    }
                    p = p->next;
                }
                if (t == 1)
                {
                    for (int i = 0; i < sum1; i++)
                    {
                        strcpy(num[i] , num[i + 1]);
                    }
                    for (int i = 0; i < sum2; i++)
                    {
                        strcpy(num2[i], num2[i + 1]);
                    }
                    sum1--;
                    sum2--;
                }
                if (k == 1)
                {
                    for (int i = 0; i < sum3; i++)
                    {
                        strcpy(num3[i], num3[i + 1]);
                    }
                    sum3--;
                }
                printf("删除成功\n");
                break;
            }
        }
        p = pr;
        pr = pr->next;
    }
    if (flag)
    {
        printf("该学生记录不存在!\n");
    }
}

void show(node* L)
{
    if (L->next== NULL)
    {
        printf("无学生信息,请先添加\n");
        return;
    }
    else
    {
        printf("注意1为到课  2为旷课  3为事假  4为病假  5为迟到  6为早退\n");
        node* pr = L->next;
        while (pr != NULL)
        {
            printf("学生学号:%s  ", pr->data.xuehao);
            printf("学生姓名:%s  ", pr->data.name);
            printf("学生班级:%s  ", pr->data.banji);
            printf("日期:%s  ", pr->data.data);
            printf("学生到课情况:%s\n", pr->data.daoke);
            pr = pr->next;
        }
    }
}

void paixv(node* L)
{
    node* pr = L->next;
    if (pr == NULL)
    {
        printf("库中无数据");
        return;
    }
    else 
    {
        printf("输入1按学号排序,输入2按姓名排序,输入3按日期排序");
        int flag;
        scanf("%d", &flag);
        if (flag == 1)
        {
            char temp[1000];
            for (int i = 0; i < sum1 - 1; i++)
            {
                for (int j = 0; j < sum1 - i - 1; j++)
                {
                    if (strcmp(num[j], num[j + 1]) > 0)
                    {
                        strcpy(temp, num[j]);
                        strcpy(num[j], num[j + 1]);
                        strcpy(num[j + 1], temp);
                    }
                }
            }
            for (int i = 0; i < sum1; i++)
            {
                node* pr2 = pr;
                while (pr2 != NULL)
                {
                    if (strcmp(pr2->data.xuehao, num[i]) == 0) 
                    {
                        printf("学生学号:%s  ", pr2->data.xuehao);
                        printf("学生姓名:%s  ", pr2->data.name);
                        printf("学生班级:%s  ", pr2->data.banji);
                        printf("日期:%s  ", pr2->data.data);
                        printf("学生到课情况:%s\n", pr2->data.daoke);
                    }
                    pr2 = pr2->next;
                }
            }
        }
        else if (flag == 2)
        {
            char temp[1000];
            for (int i = 0; i < sum2 -1; i++)
            {
                for (int j = 0; j < sum2-i-1; j++)
                {
                    if (strcmp(num2[j], num2[j+1]) > 0)
                    {
                        strcpy(temp, num2[j]);
                        strcpy(num2[j], num2[j + 1]);
                        strcpy(num2[j + 1], temp);
                    }
                }
            }
            for (int i = 0; i < sum2; i++)
            {
                node* pr2 = pr;
                while (pr2 != NULL)
                {
                    if (strcmp(pr2->data.name, num2[i]) == 0)
                    {
                        printf("学生学号:%s  ", pr2->data.xuehao);
                        printf("学生姓名:%s  ", pr2->data.name);
                        printf("学生班级:%s  ", pr2->data.banji);
                        printf("日期:%s  ", pr2->data.data);
                        printf("学生到课情况:%s\n", pr2->data.daoke);
                    }
                    pr2 = pr2->next;
                }
            }
        }
        else if (flag == 3)
        {
            char temp[1000];
            for (int i = 0; i < sum3-1 ; i++)
            {
                for (int j =0; j < sum3-i-1; j++)
                {
                    int x = (num3[j][0] - '0') * 10+(num3[j][1]-'0');
                    int y = (num3[j+1][0] - '0') * 10 + (num3[j+1][1] - '0');
                    int z = (num3[j][4] - '0') * 10 + (num3[j][5] - '0');
                    int k = (num3[j+1][4] - '0') * 10 + (num3[j+1][5] - '0');
                    if (x>y)
                    {
                        strcpy(temp, num3[j]);
                        strcpy(num3[j], num3[j+1]);
                        strcpy(num3[j+1], temp);
                    }
                    else if (x == y)
                    {
                        if (z > k)
                        {
                            strcpy(temp, num3[j]);
                            strcpy(num3[j], num3[j+1]);
                            strcpy(num3[j+1], temp);
                        }
                    }
                }
            }
            for (int i = 0; i < sum3; i++)
            {
                node* pr2 = pr;
                while (pr2 != NULL)
                {
                    if (strcmp(pr2->data.data, num3[i]) == 0)
                    {
                        printf("学生学号:%s  ", pr2->data.xuehao);
                        printf("学生姓名:%s  ", pr2->data.name);
                        printf("学生班级:%s  ", pr2->data.banji);
                        printf("日期:%s  ", pr2->data.data);
                        printf("学生到课情况:%s\n", pr2->data.daoke);
                    }
                    pr2 = pr2->next;
                }
            }
        }

    }
}

void tongji(node* L)
{
    node* pr = L->next;
    int flag;
    printf("请输入数字查看统计报表 1 考勤日报表 2 考勤汇总表 3 考勤异常表 4 请假汇总表:");
    scanf("%d", &flag);
    if (flag == 1)
    {
        for (int i = 0; i < sum3; i++)
        {
            int k = 0;
            printf("%s\t", num3[i]);
            node* p = pr;
            int sum4 = 0, sum5 = 0, sum6 = 0, sum7 = 0,sum8=0,sum9=0;
            while (p != NULL)
            {
                if (strcmp(p->data.data, num3[i]) == 0)
                {
                    if (strcmp(p->data.daoke, "1") == 0)
                    {
                        sum4++;
                    }
                    else if (strcmp(p->data.daoke, "2") == 0)
                    {
                        sum5++;
                    }
                    else if (strcmp(p->data.daoke, "3") == 0)
                    {
                        sum6++;
                    }
                    else if (strcmp(p->data.daoke, "4") == 0)
                    {
                        sum7++;
                    }
                    else if (strcmp(p->data.daoke, "5") == 0)


                    {
                        sum8++;
                    }
                    else if (strcmp(p->data.daoke, "6") == 0)
                    {
                        sum9++;
                    }
                    printf("%s\t", p->data.name);
                    k++;
                }
                p = p->next;
            }
            printf("当日总考勤人数:%d人 出勤%d人 旷课%d人 事假%d人  病假%d人  迟到%d人  早退%d人\n", k,sum4,sum5,sum6,sum7,sum8,sum9);
        }
    }
    else if (flag == 2)
    {
        for (int i = 0; i < sum1; i++)
        {
            int k = 0;
            printf("%s\t", num[i]);
            node* p = pr;
            int sum4 = 0, sum5 = 0, sum6 = 0, sum7 = 0, sum8 = 0, sum9 = 0;
            while (p != NULL)
            {
                if (strcmp(p->data.xuehao, num[i]) == 0)
                {
                    if (strcmp(p->data.daoke, "1") == 0)
                    {
                        sum4++;
                    }
                    else if (strcmp(p->data.daoke, "2") == 0)
                    {
                        sum5++;
                    }
                    else if (strcmp(p->data.daoke, "3") == 0)
                    {
                        sum6++;
                    }
                    else if (strcmp(p->data.daoke, "4") == 0)
                    {
                        sum7++;
                    }
                    else if (strcmp(p->data.daoke, "5") == 0)
                    {
                        sum8++;
                    }
                    else if (strcmp(p->data.daoke, "6") == 0)
                    {
                        sum9++;
                    }
                    printf("%s\t", p->data.name);
                    k++;
                }
                p = p->next;
            }
    
            printf("该学生总上课次数%d 出勤%d次 旷课%d次 事假%d次  病假%d次  迟到%d次  早退%d次\n", k, sum4, sum5, sum6, sum7, sum8, sum9);
        }
    }
    else if (flag == 3)
    {
        printf("注意2为旷课  3为事假  4为病假  5为迟到  6为早退\n");
        node* p = pr;
        while (p != NULL)
        {
            if (strcmp(p->data.daoke, "1") != 0)
            {
                printf("%s   %s   %s   %s    到课情况:%s\n", p->data.xuehao, p->data.name, p->data.banji, p->data.data, p->data.daoke);
            }
            p = p->next;
        }
    }
    else if (flag == 4)
    {
        printf("3为事假  4为病假  \n");
        node* p = pr;
        while (p != NULL)
        {
            if (strcmp(p->data.daoke, "3") == 0|| strcmp(p->data.daoke, "4") == 0)
            {
                printf("%s   %s   %s   %s    到课情况:%s\n", p->data.xuehao, p->data.name, p->data.banji, p->data.data, p->data.daoke);
            }
            p = p->next;
        }
    }
    else
    {
        printf("请输入正确的数字\n");
    }
}

void save(node* L)
{
    FILE* fp;
    node* pr = L->next;
    if ((fp = fopen("data.txt", "wb")) == NULL)
    {
        printf("无法打开文件\n");
        exit(0);
    }
    while (pr)
    {
        if(pr->next == NULL)
        {
            fprintf(fp, "%s\n%s\n%s\n%s\n%s", pr->data.xuehao,pr->data.name,pr->data.banji,pr->data.data,pr->data.daoke);
        }
        else
        {
        fprintf(fp, "%s\n%s\n%s\n%s\n%s\n", pr->data.xuehao, pr->data.name, pr->data.banji, pr->data.data, pr->data.daoke);
        }
        pr = pr->next;

    }
    printf("保存成功!\n");
    fclose(fp);
}

#include"Attendance system.h";


void initwindow() 
{
    printf("**************************大学学生考勤签到系统**********\n");
    printf("*-->               请输入数字实现功能                  *\n");
    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("*-->                    9 退出                         *\n");
    printf("*******************要老实上课嗷~************************\n");
    printf("请在此输入你想要进行操作前的数字:");
}

int main()
{
    node* stude;
    creatnewnode(stude);
    read(stude);
    int flag = 1;
    while (flag)//循环页面操作
    {
        initwindow();
        int n;
        scanf("%d", &n);
        switch (n)
        {
        case 1: 
            add(stude);
            printf("请输入按下回车返回主菜单");
            getchar();
            getchar();
            system("cls");
            break;
        case 2: 
            search(stude);
            printf("请输入按下回车返回主菜单");
            getchar();
            getchar();
            system("cls");
            break;
            modify(stude);
            printf("请输入按下回车返回主菜单");
            getchar();
            getchar();
            system("cls");
            break;
        case 4: 
            del(stude);
            printf("请输入按下回车返回主菜单");
            getchar();
            getchar();
            system("cls");
            break;
        case 5: 
            show(stude);
            printf("请输入按下回车返回主菜单");
            getchar();
            getchar();
            system("cls");
            break;
        case 6:
            paixv(stude);
            printf("请输入按下回车返回主菜单");
            getchar();
            getchar();
            system("cls");
            break;
        case 7:
            tongji(stude);
            printf("请输入按下回车返回主菜单");
            getchar();
            getchar();
            system("cls");
            break;
        case 8:
            save(stude);
            printf("请输入按下回车返回主菜单");
            getchar();
            getchar();
            system("cls");
            break;
        case 9:
            printf("感谢使用本系统!\n");
            flag = 0;
            break;
        default:
            printf("请输入正确的操作数!!!\n");
            break;
        }
    }
    return 0;
}

#undef UNICODE
#undef _UNICODE
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>

typedef struct s
{
    char xuehao[100];//学号
    char name[100];//姓名
    char banji[100];//班级
    char data[100];//日期
    char daoke[100];//到课情况
}stud;
typedef struct node
{
    stud data;
    struct node* next;
}node;
void creatnewnode(node*& student);
void insert(node*& L, node* p);
void read(node* L);
void search(node* student);
void add(node* L);
void modify(node* L);
void del(node* L);
void show(node* L);
void paixv(node* L);
void tongji(node* L);
void save(node* L);

  • 写回答

4条回答 默认 最新

  • ksgpjhqf 2023-03-23 22:03
    关注

    比起修改,我甚至更愿意重写一个。
    下面是我重写的代码,那个统计函数还没有写,等明天吧。

    #include <stdio.h>
    #include <stdlib.h>
    #include <malloc.h>
    #include <string.h>
    
    const char*membername[] = {"学号", "姓名", "时间"};
    
    const char *menu =    "**************************大学学生考勤签到系统**********\n"
                        "*-->               请输入数字实现功能                  *\n"
                        "*-->              1 新增学生信息数据                   *\n"
                        "*-->                  2 查找数据                       *\n"
                        "*-->               3 修改学生记录                      *\n"
                        "*-->               4 删除学生记录                      *\n"
                        "*-->             5 显示学生考勤数据列表                *\n"
                        "*-->                    6 排序                         *\n"
                        "*-->                  7 数据统计                       *\n"
                        "*-->                    8 保存                         *\n"
                        "*-->                    9 退出                         *\n"
                        "*******************要老实上课嗷~************************\n"
                        "请在此输入你想要进行操作前的数字:";
    
    template<typename listname>
    listname* next_n(listname*p, int n) {//相当于数组的p[n]
        while (p && n--) {
            p = p->next;
        }
        return p;
    }
    
    #include<stdio.h>
    
    //将计日起点定为1970年1月1日
    #define ORIGIN_YEAR 1600
    #define OFFSET_DAYS 135141
    #define int_64 long long int
    
    namespace myio {
        char c;
        bool fgetint(FILE*fp, int &num) {//会多吃右端一个字符,建议用空格、回车等分隔
            num = 0;
            while (c = fgetc(fp), c != EOF && (c < '0' || c > '9'));
            if (c == EOF)return false;
            do {
                num *= 10;
                num += c - '0';
                c = fgetc(fp);
            } while (c >= '0' && c <= '9');
            return true;
        }
    }
    
    class MyTime {
            int_64 seconds;
            static const int timemaxlength = 64;
            static char MyTimestr[timemaxlength];
            static int days, Year, Month, Day, Hour, Minute, Second;
        public:
            MyTime() {}
            ~MyTime() {};
            MyTime(int_64 seconds);
            MyTime(int days, int seconds);
            MyTime(int year, int month, int day, int hour, int minute, int second);
            void settime(int year, int month, int day, int hour = 0, int minute = 0, int second = 0);
            void gettime(int*year, int*month, int*day, int*hour, int*minute, int*second);
            int getdays();
            int_64 getseconds();
            void output(FILE *fp=stdout, const char *format = "%d年%d月%d日%d时%d分%d秒");
            void input(FILE *fp=stdin, const char *format = NULL); //无格式,强制输入六个数字,跳过一切非数字
            //加减
            MyTime operator + (int_64 seconds);
            MyTime operator - (int_64 seconds);
            int_64 operator - (MyTime&MyTime);
            //自增自减
            MyTime& operator ++();//前置
            MyTime operator ++(int);//后置
            MyTime& operator --();//前置
            MyTime operator --(int);//后置
            //赋值
            MyTime& operator = (int_64 seconds);
            MyTime& operator = (MyTime&time);
            MyTime& operator += (int_64 seconds);
            MyTime& operator -= (int_64 seconds);
            //比较
            bool operator < (MyTime&time);
            bool operator > (MyTime&time);
            bool operator ==(MyTime&time);
            bool operator <=(MyTime&time);
            bool operator >=(MyTime&time);
    };
    
    //两个升序链表合并
    template<typename listname>
    void lmerge(listname *&h, listname *&t, listname *h1, listname *e1, listname *h2, listname *e2, int (*cmp)(listname*, listname*)) {
        listname h3, *p, *q;
        t = &h3;
        for (p = h1, q = h2; p != e1 && q != e2;) {
            if (cmp(p, q) <= 0) {
                t->next = p, t = p, p = p->next;
            } else {
                t->next = q, t = q, q = q->next;
            }
        }
        while (p != e1) t->next = p, t = p, p = p->next;
        while (q != e2) t->next = q, t = q, q = q->next;
        t->next = NULL;
        h = h3.next;
    }
    
    //链表归并排序
    template<typename listname>
    void lmergesort(listname **head, int (*cmp)(listname*, listname*)) {
        listname *t, *l, *m, *r, hh;
        int w;
        for (w = 1; next_n(*head, w); w <<= 1) {
            t = &hh;
            for (l = *head; l; l = r) {
                m = next_n(l, w);
                r = next_n(m, w);
                if (!m)
                    while (l)t->next = l, t = l, l = l->next;
                else
                    lmerge(t->next, t, l, m, m, r, cmp);
            }
            *head = hh.next;
            //t->next = NULL;
        }
    }
    
    //链表查找
    template<typename listname>
    listname* search(listname *head, listname*tail, listname* p, int (*cmp)(listname*, listname*)) {
        listname *q = head;
        while (q != tail) {
            if (cmp(p, q) == 0) {
                break;
            }
            q = q->next;
        }
        return q;
    }
    
    typedef struct Node {
        char xuehao[100];//学号
        char name[100];//姓名
        char banji[100];//班级
        MyTime time;//日期
        int daoke;//到课情况
        struct Node* next;
    } node;
    
    int compare_byxuehao(node*p, node*q) {
        return strcmp(p->xuehao, q->xuehao);
    }
    
    int compare_byname(node*p, node*q) {
        return strcmp(p->name, q->name);
    }
    
    int compare_bybanji(node*p, node*q) {
        return strcmp(p->banji, q->banji);
    }
    
    int compare_bytime(node*p, node*q) {
        return p->time - q->time;
    }
    
    int compare_bydaoke(node*p, node*q) {
        return p->daoke - q->daoke;
    }
    
    int allsame(node *p, node *q) {
        return compare_byxuehao(p, q) || compare_byname(p, q) || compare_bytime(p, q);
    }
    
    int (*stu_cmp[6])(node*, node*) = {allsame, compare_byxuehao, compare_byname, compare_bytime, compare_bybanji, compare_bydaoke};
    
    void read(node* L);
    void search(node* L);
    void add(node* L);
    void output(node*p, FILE*fp = stdout);
    void modify(node* L);
    void del(node* L);
    void show(node* L, FILE*fp = stdout);
    void paixv(node* L);
    void tongji(node* L);
    void save(node* L);
    void erase(node* L);
    
    int main() {
        node stude;
        read(&stude);
        while (1) {
            int n;
            system("cls");
            printf(menu);
            fflush(stdin);
            scanf("%d", &n);
            switch (n) {
                case 1:
                    add(&stude);
                    break;
                case 2:
                    search(&stude);
                    break;
                case 3:
                    modify(&stude);
                    break;
                case 4:
                    del(&stude);
                    break;
                case 5:
                    show(&stude);
                    break;
                case 6:
                    paixv(&stude);
                    break;
                case 7:
                    //tongji(&stude);
                    break;
                case 8:
                    save(&stude);
                    break;
                case 9:
                    erase(&stude);
                    printf("感谢使用本系统!\n");
                    return 0;
                default:
                    system("cls");
                    printf("请输入正确的操作数!!!\n");
                    break;
            }
            printf("请输入按下回车返回主菜单");
            fflush(stdin);
            getchar();
        }
        return 0;
    }
    
    void read(node*L) {
        node* t = L;
        FILE* FP;
        FP = fopen("data.txt", "rb");
        if (FP == NULL) {
            printf("This file don't exist!");
            L->next = NULL;
            return;//退出函数
        }
        while (!feof(FP)) {
            t->next = (node*)malloc(sizeof(node));//创建节点中转信息
            if(fscanf(FP, "%s%s%s", t->next->xuehao, t->next->name, t->next->banji)<3){
                free(t->next);
                break;
            }
            t->next->time.input(FP);
            fscanf(FP, "%d", &t->next->daoke);
            //如果需要,在这里可以用条件判断是否free掉
            t = t->next;
        }
        t->next = NULL;
        fclose(FP);
    }
    
    void add(node*l) {
        node*t = l, *p;
        while (t->next)t = t->next;
        t->next = (node*)malloc(sizeof(node));
        printf("请输入你想新增信息的学生学号:");
        scanf("%s", t->next->xuehao);
        printf("请输入你想新增信息的学生姓名:");
        scanf("%s", t->next->name);
        printf("请输入到课时间(格式示例: 2001/1/1, 00:00:00):");
        t->next->time.input(stdin);
        printf("请输入学生班级:");
        scanf("%s", t->next->banji);
        p = l;
        while (p = search(p->next, t->next, t->next, compare_byxuehao), p != t->next) {
            if (p->time == t->next->time) {
                printf("该学生在该时间的考勤信息已存在!!");
                free(t->next);
                t->next = NULL;
                return;
            }
        }
        t = t->next;
        printf("注意1为到课  2为旷课  3为事假  4为病假  5为迟到  6为早退\n");
        printf("请输入该时间的到课情况:");
        scanf("%d", &t->daoke);
        printf("添加成功!\n");
        t->next = NULL;
    }
    
    void output(node*p, FILE*fp) {
        if (fp == stdout)fprintf(fp, "学号:");
        fprintf(fp, "%s  ", p->xuehao);
        if (fp == stdout)fprintf(fp, "姓名:");
        fprintf(fp, "%s  ", p->name);
        if (fp == stdout)fprintf(fp, "班级:");
        fprintf(fp, "%s  ", p->banji);
        if (fp == stdout)fprintf(fp, "时间:");
        p->time.output(fp, "%04d/%02d/%02d, %02d:%02d:%02d ");
        if (fp == stdout)fprintf(fp, "到课状态:");
        fprintf(fp, "%d\n", p->daoke);
    }
    
    void search(node* L) {
        node p, *q;
        printf("输入1按学号查询,输入2按姓名查询,输入3按考勤时间查询:");
        int flag;
        scanf("%d", &flag);
        if (flag >= 1 && flag <= 3) {
            int flag2 = 1;
            printf("请输入%s:", membername[flag - 1]);
            if(flag==1)scanf("%s", p.xuehao);
            else if(flag==2)scanf("%s", p.name);
            else p.time.input(stdin);
            q = L;
            while (q = search(q->next, (node*)NULL, &p, stu_cmp[flag]), q) {
                flag2 = 0;
                output(q);
            }
            if (flag2) {
                printf("%s不存在!\n", membername[flag - 1]);
            }
        }
    }
    
    void modify(node* L) {
        node p, *q;
        printf("请输入你想要修改的学生学号:");
        scanf("%s", p.xuehao);
        printf("请输入你想修改学生记录的具体时间(格式示例: 2001/1/1, 00:00:00):");
        p.time.input(stdin);
        q = L;
        while (q = search(q->next, (node*)NULL, &p, compare_byxuehao), q) {
            if (q->time == p.time) {
                printf("注意1为到课  2为旷课  3为事假  4为病假  5为迟到  6为早退\n");
                printf("请输入学生到课情况:");
                scanf("%d", &q->daoke);
                printf("修改成功!\n");
                return;
            }
        }
        printf("无该日学生信息!");
    }
    
    void del(node* L) {
        node p, *q;
        if (L->next == NULL) {
            printf("无考勤信息,请先添加");
            return;
        }
        printf("请输入你想要删除的学生记录的学生学号:");
        scanf("%s", p.xuehao);
        printf("请输入你想要删除的学生记录的具体时间(格式示例: 2001/1/1, 00:00:00):");
        p.time.input(stdin);
        q = L;
        for (q = L; q->next; q = q->next) {
            if (q->next->time == p.time && strcmp(q->next->xuehao, p.xuehao)==0) {
                p.next = q->next;
                q->next = q->next->next;
                free(p.next);
                printf("删除成功\n");
                return;
            }
        }
        printf("该学生记录不存在!\n");
    }
    
    void show(node *L, FILE*fp) {
        if (L->next == NULL) {
            printf("无学生信息,请先添加\n");
            return;
        }
        if (fp == stdout)printf("注意1为到课  2为旷课  3为事假  4为病假  5为迟到  6为早退\n");
        for (L = L->next; L; L = L->next) {
            output(L, fp);
            fputc('\n', fp);
        }
    }
    
    void paixv(node* L) {
        if (L->next == NULL) {
            printf("库中无数据");
            return;
        }
        printf("输入1按学号排序,输入2按姓名排序,输入3按日期排序");
        int flag;
        scanf("%d", &flag);
        if (flag >= 1 && flag <= 3) {
            lmergesort(&L->next, stu_cmp[flag]);
            show(L);
        }
    }
    
    void save(node* L) {
        FILE* fp;
        if ((fp = fopen("data.txt", "wb")) == NULL) {
            printf("无法打开文件\n");
            exit(0);
        }
        show(L, fp);
        printf("保存成功!\n");
        fclose(fp);
    }
    
    void erase(node* L) {
        node*p;
        for (L = L->next; L; L = p) {
            p = L->next;
            free(L);
        }
    }
    
    int MyTime::days, MyTime::Year, MyTime::Month, MyTime::Day, MyTime::Hour, MyTime::Minute, MyTime::Second;
    
    MyTime::MyTime(long long int s) {
        seconds = s;
    }
    
    MyTime::MyTime(int d, int s) {
        seconds = (int_64)d * 86400 + s;
    }
    
    MyTime::MyTime(int y, int mon, int d, int h, int min, int s) {
        settime(y, mon, d, h, min, s);
    }
    
    void MyTime::settime(int year, int month, int day, int hour, int minute, int second) {
        year -= ORIGIN_YEAR;
        seconds =
            month <= 2 ? (
                (year - 1) * 365 + (year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400
                + (month - 1) * 30 + month * 7 / 12
                + day - 1
            ) : (
                (year) * 365 + (year) / 4 - (year) / 100 + (year) / 400
                - (13 - month) * 30 - (14 - month) * 7 / 12
                + day - 1
            );
        seconds -= OFFSET_DAYS;
        seconds = seconds * 86400 + hour * 3600 + minute * 60 + second;
    }
    
    void MyTime::gettime(int*year, int*month, int*day, int*hour, int*minute, int*second) {
        days = seconds / 86400;
        Day = days + 306 + OFFSET_DAYS;
        Year = 1;
        Year += Day / 146097 * 400;
        Day %= 146097;
        Year += Day / 36524 * 100;
        Day %= 36524;
        Year += Day / 1461 * 4;
        Day %= 1461;
        Year += Day / 365;
        Day %= 365;
        if (Day < 306) {
            Year--;
        }
        Year += ORIGIN_YEAR;
        Day++;
        Month = (Day * 12 - 8) / 367 + 1;
        Day = Day - ((Month - 1) * 367 + 7) / 12;
        Month = (Month + 1) % 12 + 1;
        Second = seconds % 86400;
        Hour = Second / 3600;
        Second %= 3600;
        Minute = Second / 60;
        Second %= 60;
        if (year)*year = Year;
        if (month)*month = Month;
        if (day)*day = Day;
        if (hour)*hour = Hour;
        if (minute)*minute = Minute;
        if (second)*second = Second;
    }
    
    int MyTime::getdays() {
        return seconds / 86400;
    }
    
    void MyTime::output(FILE*fp, const char*format) {
        gettime(0, 0, 0, 0, 0, 0);
        fprintf(fp, format, Year, Month, Day, Hour, Minute, Second);
    }
    
    void MyTime::input(FILE*fp, const char*format) {
        if (format) {
            fscanf(fp, format, &Year, &Month, &Day, &Hour, &Minute, &Second);
        } else {
            myio::fgetint(fp, Year);
            myio::fgetint(fp, Month);
            myio::fgetint(fp, Day);
            myio::fgetint(fp, Hour);
            myio::fgetint(fp, Minute);
            myio::fgetint(fp, Second);
        }
        settime(Year, Month, Day, Hour, Minute, Second);
    }
    
    MyTime MyTime::operator + (int_64 s) {
        return seconds + s;
    }
    
    MyTime MyTime::operator - (int_64 s) {
        return seconds - s;
    }
    
    int_64 MyTime::operator - (MyTime&time) {
        return seconds - time.seconds;
    }
    
    MyTime& MyTime::operator = (int_64 s) {
        seconds = s;
        return *this;
    }
    
    MyTime& MyTime::operator = (MyTime&time) {
        seconds = time.seconds;
        return *this;
    }
    
    MyTime& MyTime::operator += (int_64 s) {
        seconds += s;
        return *this;
    }
    
    MyTime& MyTime::operator -= (int_64 s) {
        seconds -= s;
        return *this;
    }
    
    MyTime& MyTime::operator ++() {
        ++seconds;
        return *this;
    }
    
    MyTime MyTime::operator ++(int) {
        return seconds++;
    }
    
    MyTime& MyTime::operator --() {
        --seconds;
        return *this;
    }
    
    MyTime MyTime::operator --(int) {
        return seconds--;
    }
    
    bool MyTime::operator < (MyTime&time) {
        return seconds < time.seconds;
    }
    
    bool MyTime::operator > (MyTime&time) {
        return seconds > time.seconds;
    }
    
    bool MyTime::operator ==(MyTime&time) {
        return seconds == time.seconds;
    }
    
    bool MyTime::operator <=(MyTime&time) {
        return seconds <= time.seconds;
    }
    
    bool MyTime::operator >=(MyTime&time) {
        return seconds >= time.seconds;
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 4月1日
  • 已采纳回答 3月24日
  • 修改了问题 3月23日
  • 修改了问题 3月23日
  • 展开全部

悬赏问题

  • ¥170 如图所示配置eNSP
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果
  • ¥15 键盘指令混乱情况下的启动盘系统重装