一个简单的学生信息管理系统

时间:2023-01-17 15:52:46

    昨天忽然想写一个小型的信息管理系统了,用链表和文本文件存储信息,所以就回过头把链表看了一遍,下午的时候把框架打好了,学生信息只有学生姓名和学号。程序功能只具备:1、添加学生信息功能(内嵌查重功能),2、查找功能(根据学号查找),3、删除学生信息功能(内嵌一小小的登陆功能,登陆成功方可进行此操作)4、打印功能(把目前所有的学生信息打印出来)

        对于添加信息这里,我采取的是用链表写入信息,每次写入一个学生信息,都会去检测是不是学号已经存在了。单次写完后将这条链的所有信息保存在文本内。每个学生占一行,姓名和学号用空格隔开。这里就有一个问题:如果我在这次写入操作时,写入的前后数据学号相同,它还是会当做有效的存储起来。(因为我可能这次写入了三个学生,在三个学生信息输入完成前,是没有保存的,所以输入后面那个学号,只是和已经保存好的信息比对,导致可能写入重复的学号。) 所以,在查重那里,我觉得可以直接加上保存的功能,如果当前的同学信息有效,直接保存。但是,重复的打开关闭文件肯定会导致运行效率降低的。

        这里还有一个问题,也是以后写类似东西应该注意的地方:信息储存时,应该把最重要的东西放在前面。应该是 学号 姓名\n  而不是 姓名 学号\n。因为学号是唯一的,姓名可以重复,所以我们查找和删除都是通过学号进行,而放在前面有便于我们查找,可以节省很多操作和时间。
    
        还有就是关于保存时回车键的保存,在每行信息后都应该是一个回车键,换到文件的下一行。但是在删除那里,我是通过一个二维数组来操作的,将每行数据都保存在二维数组内,如果找到学号了,那就跳到下一行,把本应放查找的学号的同学信息一行放下一行信息,最后将整个数组给重新写入替换原来的信息。在这里出现了一个Bug:如果删除的本身就是最后一行,那么就会导致文本内格式出现错误。所以:写文件,回车符使用一定要小心!
回车符使用一定要小心!回车符使用一定要小心!

        另外,字符串结尾的 \0 别忘了,二级和写项目这个都很重要!
        

        有一个Bug是在首页的选择页面,我刚开始是用一个int型的变量来保存用户输入的选择项,用switch来控制选择的。但是用户如果不输入一个整数,输入一个文字、符号、或者是其他非数字,程序将出现不可预知的错误!所以我还是和以前一样,使用一个字符串(字符数组)保存用户的选择,如果长度大于1,那么提示错误,并按任意键返回首页,如果长度为1,将判断交给switch语句,里面的default语句可以帮助我提示用户错误信息,不至于让程序脱离掌控。

基本的代码如下:

#include <stdio.h>
#include <malloc.h>
#include <Windows.h>
#include <string.h>

/*函数声明*/
void shouye();
void AddMessage();
void chazhao();
void shanchu();
void duqu();
int panduan();
int denglu();

//定义一个学生的数据类型
struct Student
{
    char name[20];
    char num[20];
    struct Student *next;
};

//主函数
int main(void)
{
    shouye();
    return 0;
}

//首页函数
void shouye(void)
{
    char i[20] = {0};
    while(1)
    {        
        system("cls");
        printf("********这是首页********\n");
        printf("*    1、添加学生信息   *\n");
        printf("*    2、查找学生信息   *\n");
        printf("*    3、删除学生信息   *\n");
        printf("*    4、打印学生信息   *\n");
        printf("*    5、退出首页       *\n");
        printf("************************\n");
        scanf("%s",i);
        if(strlen(i) > 1)
        {
            printf("输入错误\n");
            system("pause");
            continue;
        }
        switch(i[0])
        {
            case '1':AddMessage();break;
            case '2':chazhao();break;
            case '3':shanchu();break;
            case '4':duqu();break;
            case '5':return ;
            default:printf("输入错误!\n");system("pause");break;
        }
    }
}

//添加信息函数
void AddMessage()
{
    struct Student *pHead = NULL;
    struct Student *p1,*p2;
    char flag[2] = "0";
    p1 = p2 = (struct Student*)malloc(sizeof(struct Student));
    if(p1 == NULL || NULL == p2)
    {
        printf("内存分配失败\n");
        return ;
    }
    printf("请输入学生的姓名,学号,用空格隔开,姓名为0时终止输入:");
    scanf("%s%s",p1->name,p1->num);
    while(strcmp(p1->name,"0") != 0 )
    {
        if(!panduan(p1))
            break;
        if(NULL == pHead)
            pHead = p1;
        else
            p2->next = p1;
        p2 = p1;
        p1 = (struct Student*)malloc(sizeof(struct Student));
        if(p1 == NULL)
        {
            printf("内存分配失败\n");
            return ;
        }
        printf("请输入学生的姓名,学号,用空格隔开,姓名为0时终止输入:");
        scanf("%s%s",p1->name,p1->num);
    }
    free(p1);
    p1 = NULL;
    p2->next = NULL;
    system("pause");
    return ;
}

//查找函数
void chazhao(void)
{
    char temp[20] = {0},name[20] = {0},num[20];
    FILE *fp = fopen("E:\\student.txt","r");
    system("cls");
    printf("请输入您想要查找的同学学号:");
    scanf("%s",num);
    while(fscanf(fp,"%s%s",temp,name)!=EOF)
    {
        if(strcmp(num,temp) == 0)
        {
            printf("您所查找的同学信息如下:\n");
            printf("姓名:%s 学号:%s\n",name,temp);
            system("pause");
            fclose(fp);
            return ;
        }
    }
    printf("查无此人\n");
    system("pause");
    fclose(fp);
    return ;
}

//删除操作时登陆函数
int denglu(void)
{
    char zhanghao[20] = "唐小龙",zhanghao1[20] = {0};
    int i;
    printf("请输入管理员账号:");
    scanf("%s",zhanghao1);
    if(strcmp(zhanghao,zhanghao1) == 0)
    {
        printf("请输入密码:");
        scanf("%d",&i);
        if(520 != i)
        {
            system("cls");
            printf("密码错误!\n");
            system("pause");
            return 0;
        }
    }
    else
    {
        system("cls");
        printf("账号错误!\n");
        system("pause");
        return 0;
    }
    printf("成功登陆!\n");
    system("pause");
    return 1;
}

//删除函数
void shanchu(void)
{
    int i = 0,j = 0,k = 0,l = 0,flag = 0;
    char temp[100] = {0},name[20] = {0},num[20],xin[500][50] = {0};
    FILE *fp = fopen("E:\\student.txt","r");    
    if(!denglu())
        return ;
    duqu();
    printf("\n请输入您想要删除的同学学号:");
    scanf("%s",num);
    while(fscanf(fp,"%s%s",temp,name)!=EOF)
    {        
        l++;
        i = j = 0;
        if(strcmp(temp,num) == 0)
        {
            flag = 1;
            continue;
        }
        else
        {
            while(temp[i] != '\0')
            {
                xin[k][i] = temp[i];
                i++;
            }
            xin[k][i++] = ' ';
            while(name[j] != '\0')
            {
                xin[k][i] = name[j++];
                i++;
            }
            xin[k][i] = '\n';
            xin[k][i+1] = '\0';
            k++;
        }
    }
    if(flag == 0)
    {
        printf("查无此人\n");
        system("pause");
        fclose(fp);
        return ;
    }
    else
    {
        fclose(fp);
        fp = fopen("E:\\student.txt","w");
        for(i = 0;i <= k;i++)
        {
            fprintf(fp,"%s",xin[i]);
        }
        printf("删除完成!\n");
        fclose(fp);
        system("pause");
        Sleep(1000);
    }
    duqu();
    system("pause");
    fclose(fp);
    return ;
}

//打印信息函数
void duqu(void)
{
    char num[20] = {0},name[20] = {0};
    FILE *fp = fopen("E:\\student.txt","r");
    if(fp == NULL)
    {
        printf("文件打开失败\n");
        return ;
    }
    system("cls");
    printf("\n目前已有的学生信息如下:\n");
    while(fscanf(fp,"%s%s",num,name)!=EOF)
        printf("姓名:%s 学号:%s\n",name,num);
    fclose(fp);
    printf("\n");
    system("pause");
}

//判断函数,判断写入的学号是否已经存在
int panduan(struct Student *p2)
{
    int i = 0,j = 0;
    char temp[100] = {0},temp1[20] = {0};
    FILE *fp = fopen("E:\\student.txt","r");
    while(fgets(temp,100,fp) != NULL)
    {
        while(temp[i] != ' ')
        {
            temp1[j++] = temp[i++];
        }
        temp1[j] = '\0';
        if(strcmp(p2->num,temp1) == 0)
        {
            printf("此学号已经存在,非法操作\n");
            fclose(fp);
            return 0;
        }
        i = j = 0;
    }
    fclose(fp);
    fp = fopen("E:\\student.txt","a+");
    fprintf(fp,"%s %s\n",p2->num,p2->name);
    fclose(fp);
    return 1;
}