C語言實現學生信息管理系統(文件操作)

本文實例為大傢分享瞭C語言實現學生信息管理系統的具體代碼,供大傢參考,具體內容如下

前言:與上篇文章相比,增加瞭文件操作,可將任意時期的的學生數據存儲再文件中,菜單也隨之改動,增加瞭文件操作一欄,是否存儲到相應文件中由使用者決定

新增函數——文件操作;

//學生數據文件儲存 
//儲存任意時期的學生數據 
void Store_List(Link head)
{
    //文件操作 
    ofstream ofs;
    ofs.open("Std_Information.txt",ios::out);
    
    if(head==NULL)
    {
        printf("學生為空\n");
        return; 
    }
    else
    {
        Link p=head->next;
        while(p)
        {
            ofs<< "姓名:"<<p->data.studentName<<"    學號:"<<p->data.studentNo<<"  成績:"<<p->data.score<<endl; 
            p=p->next;
        }
        
    }
}

1.頭文件和預處理

#include <stdio.h>
#include<string.h>
#include<malloc.h>
#include<stdlib.h>
#include<stdbool.h>
#include<iostream>
#include<fstream>//文件操作所需頭文件 
using namespace std;
#define NO_LENGTH  20
#define NAME_LENGTH 11

/* 定義學生結構體的數據結構 */
typedef struct Student{
    char studentNo[NO_LENGTH];
    char studentName[NAME_LENGTH];
    int score;
}st;

/* 定義每條記錄或節點的數據結構 */
typedef struct node
{
    struct Student data; //數據域
    struct node *next; //指針域
}Node,*Link;  //Node為node類型的別名,Link為node類型的指針別名

2.定義學生結構體的數據結構

typedef struct Student{
    char studentNo[NO_LENGTH];
    char studentName[NAME_LENGTH];
    int score;
}st;

3.定義每條記錄或節點的數據結構

/* 定義每條記錄或節點的數據結構 */
typedef struct node
{
    struct Student data; //數據域
    struct node *next; //指針域
}Node,*Link;  //Node為node類型的別名,Link為node類型的指針別名

4.函數接口代碼.

1.定義提示菜單

//定義提示菜單
void myMenu(){

    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"); 
    
}

2.增加學生記錄

void inputStudent(Link l){
     printf("請輸入學生學號:");
     scanf("%s",l->data.studentNo);
     printf("請輸入學生的姓名:");
     scanf("%s",l->data.studentName);
    printf("請輸入學生的成績:");
     scanf("%s",&(l->data.score));
     //每個新創建的節點的next域都初始化為NULL
     l->next = NULL;
     system("cls");
}

3.輸入學號接口·

void inputStudentNo(char s[],char no[]){
    printf("請輸入要%s的學生學號:",s);
    scanf("%s",no);
}

4.遍歷表中學生

//遍歷表中學生 
void displayNode(Link head){
    if(head==NULL)
    {
        printf("學生為空\n");
        return; 
    }
    else
    {
        Link p=head->next;
        while(p)
        {
            cout<<"姓名:"<<p->data.studentName<<"    學號"<<p->data.studentNo<<"  成績:"<<p->data.score<<endl; 
            p=p->next;
        }
        
    }
   // 填寫代碼,根據傳入的鏈表head頭指針,掃描鏈表顯示所有節點的信息
   system("pause");
   system("cls");
}

5.增加學生記錄

/* 增加學生記錄 */
bool addNode(Link head){
     Link p,q;   //p,q兩個節點一前一後
     Link node;  //node指針指向新創建的節點
     node=(Link)malloc(sizeof(Node));
     inputStudent(node);

     q = head;
     p = head->next;  //q指向head後面的第一個有效節點
     if(head->next==NULL)
         //鏈表為空時
        head->next = node;
     else {
         //循環訪問鏈表中的所有節點
        while(p != NULL){
            if (node->data.studentNo < p->data.studentNo){
                //如果node節點的學號比p節點的學號小,則插在p的前面,完成插入後,提前退出子程序
                q->next = node;
                node->next = p;
                return true;
            }
            else{
                //如果node節點的學號比p節點的學號大,繼續向後移動指針(依然保持pq一前一後)
                q = p;
                p = p->next;

            }
        }
        //如果沒能提前退出循環,則說明之前沒有插入,那麼當前node節點的學號是最大值,此時插在鏈表的最後面
        q->next = node;

    }
     return true;
     system("pause");
   system("cls");
}

6.刪除學生信息

//刪除學生信息
bool deleteNode(Link head){
    // 按照給定的學號刪除學生記錄,如果刪除成功返回true,如果沒找到學號返回false

    //輸入要處理的學號
        char no[NO_LENGTH];
    inputStudentNo("刪除",no);
        Link p=head->next;
    Link q=head;
    while(p)
    {
        if(strcmp(p->data.studentNo,no)==0)
        {
            cout<<"成功刪除該學生"<<endl; 
            q->next=p->next;
            free(p);
            system("pause");
               system("cls");
            return true;
        }
        else
        {
            q=p;
            p=p->next;
        }
    }
    cout<<"未找到該學生"<<endl; 
        system("pause");
           system("cls");
    return false;
}

7.查找學生信息

//查找學生信息 
bool queryNode(Link head){
    // 按照給定的學號查詢學生記錄,如果查找成功返回true,如果沒找到學號返回false

    //輸入要處理的學號
    char no[NO_LENGTH];
    inputStudentNo("查找",no);
        Link p=head->next;
    while(p)
    {
        if(strcmp(p->data.studentNo,no)==0)
        {
            
               system("cls");
               cout<<"姓名:"<<p->data.studentName<<"    學號:"<<p->data.studentNo<<"  成績:"<<p->data.score<<endl; 
            return true;
        }
        else
        {
            p=p->next;
        }
    }
    cout<<"未找到該學生"<<endl; 
   system("cls");

    return false;
}

8.修改學生信息

//修改學生信息 
bool modifyNode(Link head){
    // 按照給定的學號找到學生記錄節點,如果修改成功返回true,如果沒找到學號返回false
    
    //輸入要處理的學號
    char no[NO_LENGTH];
    inputStudentNo("修改",no);
    Link p=head->next;
    while(p)
    {
        if(strcmp(p->data.studentNo,no)==0)
        {
            cout<<"請輸入修改後的姓名"<<endl; 
            cin>>p->data.studentName;
            cout<<"請輸入修改後的學號"<<endl; 
            cin>>p->data.studentNo;
            cout<<"請輸入修改後的成績"<<endl; 
            cin>>p->data.score;
            system("cls");
            return true;
        }
        else
        {
            p=p->next;
        }
    }
    cout<<"未找到該學生,請重新輸入學號"<<endl; 
    system("cls");
    return false;
}

9.統計學生人數

//統計學生人數
int countNode(Link head){
    //統計學生人數,掃描鏈表統計節點個數,返回節點數
    Link p;
    int count = 0;
    p = head->next;
    while(p)
    {
        p=p->next;
        count++;
    }
    //填充代碼
    system("cls");
    return count;
}

10.清空鏈表

//清空鏈表 
void clearLink(Link head){
    Link q,p;
    p=head->next;
    q=head;
    while(p)
    {
        q->next=p->next;
        free(p);
        p=q->next;
    }
        //遍歷鏈表,用free語句刪除鏈表中用malloc建立起的所有的節點
}

11.文件操作

//學生數據文件儲存 
//儲存任意時期的學生數據 
void Store_List(Link head)
{
    //文件操作 
    ofstream ofs;
    ofs.open("Std_Information.txt",ios::out);
    
    if(head==NULL)
    {
        printf("學生為空\n");
        return; 
    }
    else
    {
        Link p=head->next;
        while(p)
        {
            ofs<< "姓名:"<<p->data.studentName<<"    學號:"<<p->data.studentNo<<"  成績:"<<p->data.score<<endl; 
            p=p->next;
        }
        
    }
}

5.main函數

int main() {
    int select;
        int count;
    Link head;  // 定義鏈表

    //建立head頭結點,在這個程序中head指向頭結點,頭結點data部分沒有內容,其後續節點才有真正的數據
    head = (Link)malloc(sizeof(Node));
    head->next = NULL;

    while(1)
    {
        myMenu();
        printf("\n請輸入你的選擇(0-7):");  //顯示提示信息
        scanf("%d",&select);
        switch(select)
        {
        case 1:
            //增加學生記錄
            if(addNode(head))
                printf("成功插入一個學生記錄。\n\n");
            break;
        case 2:
            //刪除學生記錄
            if(deleteNode(head))
                printf("成功刪除一個學生記錄。\n\n");
            else
                printf("沒有找到要刪除的學生節點。\n\n");
            break;
        case 3:
            //查詢學生記錄
            if(queryNode(head))
                printf("成功找到學生記錄。\n\n");
            else
                printf("沒有找到要查詢的學生節點。\n\n");
            break;
        case 4:
            //修改學生記錄
            if(modifyNode(head))
                printf("成功修改一個學生記錄。\n\n");
            else
                printf("沒有找到要修改的學生節點。\n\n");
            break;
        case 5:
            //統計學生人數
            count = countNode(head);
            printf("學生人數為:%d\n\n",count);
            break;
        case 6:
            //顯示學生記錄
            displayNode(head);
            break;
        case 7:
            //退出前清除鏈表中的所有結點
            clearLink(head);
            return 0;
        default:
            printf("輸入不正確,應該輸入0-7之間的數。\n\n");
            system("cls"); 
            break;
        }
    }
    return 0;
}

6.學生信息管理系統總源碼(可直接復制運行)

#include <stdio.h>
#include<string.h>
#include<malloc.h>
#include<stdlib.h>
#include<stdbool.h>
#include<iostream>
#include<fstream>//文件操作所需頭文件 
using namespace std;
#define NO_LENGTH  20
#define NAME_LENGTH 11

/* 定義學生結構體的數據結構 */
typedef struct Student{
    char studentNo[NO_LENGTH];
    char studentName[NAME_LENGTH];
    int score;
}st;

/* 定義每條記錄或節點的數據結構 */
typedef struct node
{
    struct Student data; //數據域
    struct node *next; //指針域
}Node,*Link;  //Node為node類型的別名,Link為node類型的指針別名

//定義提示菜單
void myMenu(){

    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"); 
    
}

void inputStudent(Link l){
     printf("請輸入學生學號:");
     scanf("%s",l->data.studentNo);
     printf("請輸入學生的姓名:");
     scanf("%s",l->data.studentName);
    printf("請輸入學生的成績:");
     scanf("%d",&(l->data.score));
     //每個新創建的節點的next域都初始化為NULL
     l->next = NULL;
     system("cls");
}

void inputStudentNo(char s[],char no[]){
    printf("請輸入要%s的學生學號:",s);
    scanf("%s",no);
}
//遍歷表中學生 
void displayNode(Link head){
    if(head==NULL)
    {
        printf("學生為空\n");
        return; 
    }
    else
    {
        Link p=head->next;
        while(p)
        {
            cout<<"姓名:"<<p->data.studentName<<"    學號"<<p->data.studentNo<<"  成績:"<<p->data.score<<endl; 
            //ofs<< "姓名:"<<p->data.studentName<<"    學號"<<p->data.studentNo<<"  成績:"<<p->data.score<<endl; 
            p=p->next;
        }
        
    }
   // 填寫代碼,根據傳入的鏈表head頭指針,掃描鏈表顯示所有節點的信息
   system("pause");
   system("cls");
}

/* 增加學生記錄 */
bool addNode(Link head){
     Link p,q;   //p,q兩個節點一前一後
     Link node;  //node指針指向新創建的節點
     node=(Link)malloc(sizeof(Node));
     inputStudent(node);

     q = head;
     p = head->next;  //q指向head後面的第一個有效節點
     if(head->next==NULL)
         //鏈表為空時
        head->next = node;
     else {
         //循環訪問鏈表中的所有節點
        while(p != NULL){
            if (node->data.studentNo < p->data.studentNo){
                //如果node節點的學號比p節點的學號小,則插在p的前面,完成插入後,提前退出子程序
                q->next = node;
                node->next = p;
                return true;
            }
            else{
                //如果node節點的學號比p節點的學號大,繼續向後移動指針(依然保持pq一前一後)
                q = p;
                p = p->next;

            }
        }
        //如果沒能提前退出循環,則說明之前沒有插入,那麼當前node節點的學號是最大值,此時插在鏈表的最後面
        q->next = node;

    }
     return true;
     system("pause");
   system("cls");
}

bool deleteNode(Link head){
    // 按照給定的學號刪除學生記錄,如果刪除成功返回true,如果沒找到學號返回false

    //輸入要處理的學號
        char no[NO_LENGTH];
    inputStudentNo("刪除",no);
        Link p=head->next;
    Link q=head;
    while(p)
    {
        if(strcmp(p->data.studentNo,no)==0)
        {
            cout<<"成功刪除該學生"<<endl; 
            q->next=p->next;
            free(p);
            system("pause");
               system("cls");
            return true;
        }
        else
        {
            q=p;
            p=p->next;
        }
    }
    cout<<"未找到該學生"<<endl; 
system("pause");
   system("cls");
    return false;
}

//查找學生信息 
bool queryNode(Link head){
    // 按照給定的學號查詢學生記錄,如果查找成功返回true,如果沒找到學號返回false

    //輸入要處理的學號
    char no[NO_LENGTH];
    inputStudentNo("查找",no);
        Link p=head->next;
    while(p)
    {
        if(strcmp(p->data.studentNo,no)==0)
        {
            
               system("cls");
               cout<<"姓名:"<<p->data.studentName<<"    學號:"<<p->data.studentNo<<"  成績:"<<p->data.score<<endl; 
            return true;
        }
        else
        {
            p=p->next;
        }
    }
    cout<<"未找到該學生"<<endl; 
   system("cls");

    return false;
}

//修改學生信息 
bool modifyNode(Link head){
    // 按照給定的學號找到學生記錄節點,如果修改成功返回true,如果沒找到學號返回false
    
    //輸入要處理的學號
    char no[NO_LENGTH];
    inputStudentNo("修改",no);
    Link p=head->next;
    while(p)
    {
        if(strcmp(p->data.studentNo,no)==0)
        {
            cout<<"請輸入修改後的姓名"<<endl; 
            cin>>p->data.studentName;
            cout<<"請輸入修改後的學號"<<endl; 
            cin>>p->data.studentNo;
            cout<<"請輸入修改後的成績"<<endl; 
            cin>>p->data.score;
            system("cls");
            return true;
        }
        else
        {
            p=p->next;
        }
    }
    cout<<"未找到該學生,請重新輸入學號"<<endl; 
    system("cls");
    return false;
}

//統計學生人數
int countNode(Link head){
    //統計學生人數,掃描鏈表統計節點個數,返回節點數
    Link p;
    int count = 0;
    p = head->next;
    while(p)
    {
        p=p->next;
        count++;
    }
    //填充代碼
    system("cls");
    return count;
}

//清空鏈表 
void clearLink(Link head){
    Link q,p;
    p=head->next;
    q=head;
    while(p)
    {
        q->next=p->next;
        free(p);
        p=q->next;
    }
        //遍歷鏈表,用free語句刪除鏈表中用malloc建立起的所有的節點
}

//學生數據文件儲存 
//儲存任意時期的學生數據 
void Store_List(Link head)
{
    //文件操作 
    ofstream ofs;
    ofs.open("Std_Information.txt",ios::out);
    
    if(head==NULL)
    {
        printf("學生為空\n");
        return; 
    }
    else
    {
        Link p=head->next;
        while(p)
        {
            ofs<< "姓名:"<<p->data.studentName<<"    學號:"<<p->data.studentNo<<"  成績:"<<p->data.score<<endl; 
            p=p->next;
        }
        
    }
}
int main() {
    int select;
        int count;
    Link head;  // 定義鏈表
    
    
    //建立head頭結點,在這個程序中head指向頭結點,頭結點data部分沒有內容,其後續節點才有真正的數據
    head = (Link)malloc(sizeof(Node));
    head->next = NULL;

    while(1)
    {
        myMenu();
        printf("\n請輸入你的選擇(0-8):");  //顯示提示信息
        scanf("%d",&select);
        switch(select)
        {
        case 1:
            //增加學生記錄
            if(addNode(head))
                printf("成功插入一個學生記錄。\n\n");
            break;
        case 2:
            //刪除學生記錄
            if(deleteNode(head))
                printf("成功刪除一個學生記錄。\n\n");
            else
                printf("沒有找到要刪除的學生節點。\n\n");
            break;
        case 3:
            //查詢學生記錄
            if(queryNode(head))
                printf("成功找到學生記錄。\n\n");
            else
                printf("沒有找到要查詢的學生節點。\n\n");
            break;
        case 4:
            //修改學生記錄
            if(modifyNode(head))
                printf("成功修改一個學生記錄。\n\n");
            else
                printf("沒有找到要修改的學生節點。\n\n");
            break;
        case 5:
            //統計學生人數
            count = countNode(head);
            printf("學生人數為:%d\n\n",count);
            break;
        case 6:
            //顯示學生記錄
            displayNode(head);
            break;
        case 7:Store_List(head);
                cout<<"打印成功"<<endl; 
                system("pause");
                   system("cls");
            break;
        case 8:
            //退出前清除鏈表中的所有結點
            clearLink(head);
            return 0;
        default:
            printf("輸入不正確,應該輸入0-8之間的數。\n\n");
            system("pause");
            system("cls"); 
            break;
        }
    }
    return 0;
}

7.測試結果

以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: