Linux环境下C语言实现简单的基于文件的学生信息管理系统

一般来说程序运行时的数据都是存储在内存当中的,当程序结束数据也就消失了。在学习了文件操作以后,便想到可以通过读写文件来对数据进行操作,于是尝试编写了一个简单基于文件的学生信息管理系统。

学生信息可以提前按特定的格式存储在文件当中,打开程序后会先对文件进行读操作,将文件中的字符数据保存到程序的链表当中,在程序中可以对链表进行增删改查的操作来管理学生的信息,当结束程序时,会重新将链表中的数据按特定的格式存储到文件当中,这样即使程序结束也可以将数据保存下来,当下一次运行程序时还会重新将数据读取。

下面是具体的实现。


用来存储学生信息的链表,这里只涉及学号和姓名。

typedef struct Student_information
{
    char *stu_num;
    char *stu_name;
    struct Student_information *next;
}S;

将学生信息存储到链表中的函数。

void input_inf(S **head,char *num,char *name)
{
    S *tmp = malloc(sizeof(S));
    S *find = *head;
    char *buf = malloc(20);
    char *buf1 = malloc(20);
    strcpy(buf,name);
    strcpy(buf1,num);

    tmp->stu_num = buf1;
    tmp->stu_name = buf;
    tmp->next = NULL;
    if(*head == NULL)
    {
        *head = tmp;
    }
    else
    {
        while(find->next!=NULL)
        {
            find = find->next;
        }
        find->next = tmp;
    }
}

将文件中学生信息存入链表,返回学生人数。

int read_file(FILE *fp,S **head)
{
    int sum=0;
    ssize_t len;
    size_t l = 0;
    char *buf=NULL;
    int i=0,j=0;
    while((len = getline(&buf,&l,fp))!=-1)
    {
        char *name=malloc(20);
        char *num=malloc(20);
        while(*(buf+i)>='0'&&*(buf+i)<='9')
        {
            *(num+j++) = *(buf+i++);
        }
        j = 0;
        i++;
        while(*(buf+i)!='\n')
        {
            *(name+j++)=*(buf+i++);
        }
        input_inf(head,num,name);
        num = 0;
        i = 0;
        j = 0;
        free(name);
        free(buf);
        buf = NULL;
        l = 0;
        sum++;
    }
    return sum;
}

将链表数据按格式写入文件。

void write_file(FILE *fp,S *head)
{
    S *find = head;
    if(head==NULL)
        return;
    while(find->next!=NULL)
    {
        fputs(find->stu_num,fp);
        fputc(' ',fp);
        fputs(find->stu_name,fp);
        fputc('\n',fp);
        find = find->next;
    }
    fputs(find->stu_num,fp);
    fputc(' ',fp);
    fputs(find->stu_name,fp);
    fputc('\n',fp);
}

显示所有学生信息。


void show_all_inf(S *head)
{
    S *find = head;
    if(find==NULL)
    {
        printf("请先输入学生信息!\n");
        return;
    }
    while(find->next!=NULL)
    {
        printf("Student No.%s\tStudent Name:%s\n",find->stu_num,find->stu_name);
        find = find->next;
    }
    printf("Student No.%s\tStudent Name:%s\n",find->stu_num,find->stu_name);
}

通过学号查找输出学生信息。

void search(S* head,char *num)
{
    S *find = head;
    while(strcmp(find->stu_num,num)!=0)
    {
        if(find->next==NULL)
        {
            printf("未找到该学生!\n");
               return;
        }
        find = find->next;
    }
    printf("学号No.%s的学生姓名为%s\n",num,find->stu_name);
}

查看链表中是否存在相同学号,存在返回1,不存在返回0。用在添加学生信息时,保证学号为主键。

int if_in(S *head,char *num)
{
    S *find = head;
    if(head==NULL)
    {
        return 0;
    }
    while(strcmp(find->stu_num,num)!=0)
    {
        if(find->next==NULL)
            return 0;
        find = find->next;
    }
    return 1;
}

通过学号删除学生信息。

void del(S **head,char *num,int *sum)
{
    S *find = *head;
    S *front = NULL;
    if(*head == NULL)
    {
        printf("已无学生信息!\n");
        return;
    }
    while(strcmp(find->stu_num,num)!=0)
    {
        if(find->next==NULL)
        {
            printf("该学号不存在!\n");
            return;
        }
        front = find;
        find = find->next;
    }
    printf("学号No.%s的学生姓名为%s\n[1]确认删除 [其他]取消(请勿输入字符!)\n",num,find->stu_name);
    int select;
    scanf("%d",&select);
    if(select==1)
    {
        if(find==*head)
        {
            *head = find->next;
            find->next = NULL;
            free(find);
        }
        else
        {
            front->next = find->next;
            find->next = NULL;
            free(find);
        }
        *sum--;
        printf("删除成功!");
    }
}

主函数通过printf和switch实现了简单的界面。这里注意在switch之后需要加一个getchar( ),因为在选择功能时虽然通过scanf输入了一个字符,但实际上还多输入了一个回车,即换行符’\n’,而switch结束后进入下一次循环选择功能时scanf会直接把这个回车符读入进行选择,而不是等待用户的输入,在linux redhat是这样的,所以通过getchar( )来将多余的’\n’读掉。

int main()
{
    S *head = NULL;
    int sum = 0;
    char select = '1';

    //读文件信息
    FILE *fp = fopen(FILENAME,"r");
    if(fp == NULL)
    {
        printf("数据库错误!");
        exit(EXIT_FAILURE);
    }
    sum = read_file(fp,&head);
    fclose(fp);
    system("clear");

    //主程序功能部分
    while(select!='q')
    {
        char *name = malloc(20);
        char *num = malloc(20);
        char *search_num = malloc(20);
        printf("***  Student Manage System  ***\n");
        printf("***  [1] 添加学生信息       ***\n");
        printf("***  [2] 列出所有学生信息   ***\n");
        printf("***  [3] 查询学生信息       ***\n");
        printf("***  [4] 学生总数查询       ***\n");
        printf("***  [5] 删除学生信息       ***\n");
        printf("***  [q] 退出               ***\n");
        printf("请选择:");
        scanf("%c",&select);
        switch(select)
        {
            case '1':
                printf("学生学号:");
                scanf("%s",num);
                printf("学生姓名:");
                scanf("%s",name);
                printf("您要添加的学生学号为No.%s,姓名为%s\n",num,name);
                printf("*** [1] 确认添加 [其他]取消(请勿输入字符!)\n");
                printf("请选择:");
                int chose = 0;
                scanf("%d",&chose);
                if(chose==1)
                {
                    if(if_in(head,num))
                    {
                        printf("学号已存在!请重新输入!\n");
                    }
                    else
                    {
                        input_inf(&head,num,name);
                        sum++;
                        printf("添加成功!\n");
                    }
                }
                else
                {
                    printf("已取消!\n");
                }
                printf("---  3s后返回主页面  ---\n");
                sleep(3);
                system("clear");
                break;

            case '2':
                show_all_inf(head);
                printf("---  3s后返回主页面  ---\n");
                sleep(3);
                system("clear");
                break;
            case '3':
                printf("输入学生学号:");
                scanf("%s",search_num);
                search(head,search_num);
                printf("---  3s后返回主页面  ---\n");
                sleep(3);
                system("clear");
                break;
            case 'q':
                break;
            default:
                printf("请重新选择!\n");
                select = '1';
                search(head,search_num);
                printf("---  3s后返回主页面  ---\n");
                sleep(3);
                system("clear");
                break;

            case '4':
                printf("学生总数为%d人。\n",sum);
                printf("---  3s后返回主页面  ---\n");
                sleep(3);
                system("clear");
                break;

            case '5':
                printf("输入要删除学生的学号:");
                scanf("%s",search_num);
                del(&head,search_num,&sum);
                printf("---  3s后返回主页面  ---\n");
                sleep(3);
                system("clear");
                break;
        }
        getchar();//这个getchar非常重要!用来读掉回车符!
    }
    FILE *fw = fopen(FILENAME,"w+");
    write_file(fw,head);

    return 0;
}

以下是需要的头文件

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define FILENAME "Stu_data"
  • 4
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值