基于链表+文件储存的学生宿舍(寝室)管理系统课设(文末附源码)

该课设亮点:采用多种算法实现排序

二分法、冒泡排序、指针数组、基于文件操作读取取或保存文件

运行功能界面如下:

基于链表+文件储存的学生宿舍(寝室)管理系统课设(文末附源码)_第1张图片

添加学生:

基于链表+文件储存的学生宿舍(寝室)管理系统课设(文末附源码)_第2张图片

当有了学生信息后,可以查看所有的学生信息:可以通过各种排序,明了的看数据:

基于链表+文件储存的学生宿舍(寝室)管理系统课设(文末附源码)_第3张图片

当编辑修改学生的学号不存在时,即报错:

基于链表+文件储存的学生宿舍(寝室)管理系统课设(文末附源码)_第4张图片

学号存在时,即可编辑:

基于链表+文件储存的学生宿舍(寝室)管理系统课设(文末附源码)_第5张图片

按姓名查找学生:

基于链表+文件储存的学生宿舍(寝室)管理系统课设(文末附源码)_第6张图片

按学号查找学生:

基于链表+文件储存的学生宿舍(寝室)管理系统课设(文末附源码)_第7张图片

按宿舍号去查学生:

基于链表+文件储存的学生宿舍(寝室)管理系统课设(文末附源码)_第8张图片

将所有的数据保存到文件:

基于链表+文件储存的学生宿舍(寝室)管理系统课设(文末附源码)_第9张图片

最后,下次运行,即可继续运行上次保存的数据:(需要先输入1读取数据,再输入2显示所有的数据,否则报错)

基于链表+文件储存的学生宿舍(寝室)管理系统课设(文末附源码)_第10张图片

代码如下:

腾讯文档-访问课设代码腾讯文档-在线文档icon-default.png?t=N7T8https://docs.qq.com/doc/p/71239d69a76f56cf1521717ae6b22c27cf876f10课设代码太多接近600多行

//定义数据文件为符号常量。
#define DATA_FILE "./data.dat"
#define MAX_SIZE 100
#define DORM_MAX_NUM 8 // 一个宿舍最多住多少人
//定义住宿信息结构体。
typedef struct dormitory
{
    char dormID[10];
    char studentID[10];
    char sex[10]; // 0:男生,1:女生
    char Name[10];
} dormitory;
//定义住宿信息链表结点,包括 dormitory 型的数据域和指向下一个结点的指针域。
typedef struct node_dormitory
{
    dormitory data;
    struct node_dormitory *next;
} node_dormitory, *p_node_dormitory;
//定义住宿信息链表的头指针为全局变量。
p_node_dormitory headDormitory;
//定义 3 个指针数组,分别按照关键字学号、姓名和宿舍号顺序存储住宿信息的结点地址。
dormitory *arrayDormID[MAX_SIZE], *arrayStudentID[MAX_SIZE], *arrayName[MAX_SIZE];
int countRecord;
//下列函数是输出住宿信息时要调用的函数,为了输出格式便于查看,在输出住宿信息之前输
//出住宿信息的表头(宿舍号、学号、姓名)。
void PrintTitle()
{
    printf("---------------------------------------------------\n");
    printf("      宿舍号 |        学号 |        名字 |       性别 \n");
}
//下列函数是输出结点 p 所代表的住宿信息的内容(宿舍号、学号、姓名)。
void PrintDormitory(dormitory p)
{
    printf(" %10s", p.dormID);
    printf(" | %10s", p.studentID);
    printf(" | %10s", p.Name);
    if (strcmp(p.sex, "0") == 0) {
        char *s = "男";
        printf(" | %10s\n", s);
    } else {
        char *s = "女";
        printf(" | %10s\n", s);
    }
    
}
//下列函数是根据姓名查找函数,功能是采用二分查找法在姓名指针数组中查找结点。A
void searchWithName(char *key)
{
    int low, high, mid, i, matchCount; //matchCount 为匹配记录数目
    low = 0;
    high = countRecord - 1;
    matchCount = 0;
    while(low <= high)
    {
        mid = (low + high) / 2;
        if(strcmp(arrayName[mid]->Name, key) == 0)
        {
            PrintTitle();
            i = mid - 1;
            while(i >= low)
            {
                if(strcmp(arrayName[i]->Name, key) == 0)
                    i--;
                else
                    break;
            }
            low = i + 1; //low 此时为匹配的第一条记录下标
            i = mid;
            while(i <= high)
            {
                if(strcmp(arrayName[i]->Name, key) == 0)
                    i++;
                else
                    break;
            }
            high = i - 1; //high 此时为匹配的最后一条记录下标
            matchCount = high - low + 1;
            for(i = low; i <=high; i++)
                PrintDormitory(*arrayName[i]);
            printf("\n共找到%d条数据\n", matchCount);
            getchar();
            return;
        }
        else if(strcmp(arrayName[mid]->Name, key) < 0)
            low = mid + 1;
        else
            high = mid - 1;
    }
    printf("\n404 没有找到");
    getchar();
}
//下列函数是根据学号查找函数,功能是采用二分查找法在学号指针数组中查找结点。A
void searchWithStudentID(char *key)
{
    int low, high, mid;
    low = 0;
    high = countRecord - 1;
    while(low <= high)
    {
        mid = (low + high) / 2;
        if(strcmp(arrayStudentID[mid]->studentID, key) == 0)
        {
            PrintTitle();
            PrintDormitory(*arrayStudentID[mid]);
            printf("\n找到1条数据\n");
            getchar();
            return;
        }
        else if(strcmp(arrayStudentID[mid]->studentID, key) < 0)
            low = mid + 1;
        else
            high = mid - 1;
    }
    printf("\n404 没有找到");
    getchar();
}
//下列函数是写入文件,功能是把住宿信息链表中的内容保存到数据文件中。添加、修改、删
//除链表的函数完成操作后,只是链表的内容改变了,并没有把修改后的内容写入到数据文件中,
//只有调用下列函数,修改后的内容才写入数据文件中。D
void writeDataToFile()
{
    FILE *fp;
    p_node_dormitory pNodeDormitory;
    int count = 0;
    if((fp = fopen(DATA_FILE, "wb+")) == NULL)
    {
        printf("文件已损坏!\n");
        return;
    }
    pNodeDormitory = headDormitory;
    while(pNodeDormitory != NULL)
    {
        if(fwrite(&pNodeDormitory->data, sizeof(dormitory), 1, fp) != 1)
            printf("文件写入失败!\n");
        pNodeDormitory = pNodeDormitory->next;
        count++;
    }
    fclose(fp);
    printf("成功写入%d条数据!\n", count);
    getchar();
}
// 通过宿舍号查询到对应的信息  -1代表失败  0 代表添加成功 A
int jiaoyanDormNumAndSex(char *key, char *sex)
{
    // 男女不能混住
    int low, high, mid, index, matchCount; //matchCount 为匹配记录数目
    low = 0;
    high = countRecord - 1;
    matchCount = 0;
    while(low <= high)
    {
        mid = (low + high) / 2;
        if(strcmp(arrayDormID[mid]->dormID, key) == 0)
        {
            index = mid - 1;
            while(index >= low)
            {
                if(strcmp(arrayDormID[index]->dormID, key) == 0)
                    index--;
                else
                    break;
            }
            low = index + 1; //low 此时为匹配的第一条记录下标
            index = mid;
            while(index <= high)
            {
                if(strcmp(arrayDormID[index]->dormID, key) == 0)
                    index++;
                else
                    break;
            }
            high = index - 1; //high 此时为匹配的最后一条记录下标
            matchCount = high - low + 1;
            if (matchCount == DORM_MAX_NUM) {
                printf("\n添加失败??\n");
                printf("\n%s号宿舍只能住%d个人,目前已经住满!\n", key, DORM_MAX_NUM);
                getchar();
                return -1;
            }
            for(index = low; index <=high; index++) {
                if (strcmp(arrayDormID[index]->sex, sex) != 0) {
                    printf("\n添加失败??\n");
                    if (strcmp(arrayDormID[index]->sex, "0") == 0) {
                        printf("\n%s号宿舍是男宿舍不能住女生\n", key);
                    } else {
                        printf("\n%s号宿舍是女宿舍不能住男生\n", key);
                    }
                    
                    getchar();
                    return -1;
                } else {
                    low = 1;
                    high = 0;
                }
            }
        }
        else if(strcmp(arrayDormID[mid]->dormID, key) < 0)
            low = mid + 1;
        else
            high = mid - 1;
    }
    
    return 0;
    
}
int main()
{
    int choice = 0;
    countRecord = 0;
    headDormitory = NULL;
    int num = 0;
    do
    {
        if (num == 0) {
            printf("***********欢迎使用宿舍管理系统***********\n");
        }
        num = 1;
        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("0. 退出.\n");
        printf("\n----------------------------------\n\n");
        printf("\n\n");
        printf("请选择:");
        scanf("%d", &choice);
        switch(choice)
        {
            case 1://读入文件
                readFile(); break;
            case 2://显示全部住宿信息 排序
                view(); break;
            case 3://添加一条住宿信息 查 增
                add(); break;
            case 4://修改一条住宿信息
                edit(); break;
            case 5://删除一条住宿信息
                delete(); break;
            case 6://根据姓名查找
                find(1); break;
            case 7://根据学号查找
                find(2); break;
            case 8://根据住宿号查找
                find(3); break;
            case 9://写入文件
                writeDataToFile(); break;
            case 0://退出系统
                break;
            default://输入错误
                printf("Your choice must between 0 to 9!");
        }
    }while(choice != 0);
    
    return 0;
}

你可能感兴趣的:(链表,数据结构,c语言)