C語言實踐課程報告附源碼(學生成績管理系統 )

聲明:本課程報告比較簡陋,僅供學習參考哦!!(源碼見文章末尾)


目錄

1. 引言

1.1  研究背景

1.2  研究意義

2. 需求分析

3. 概要設計設計

3.1 功能模塊設計

3.2 主函數的流程設計

4.  詳細設計和實施

4.1 主界面設計

4.2 錄入信息

4.3 查詢信息

4.4 修改信息

4.5 添加學生

4.6 刪除學生信息

4.7 統計學生信息

5.   測試數據與測試結果

5.1 系統測試

5.2 問題分析

5.3 總結

參考文獻


 

1. 引言

1.1  研究背景

隨着科技的不斷髮展,計算機的應用領域越來越廣。在我國的各類學校,尤其是高等院校,近些年由於闊招生員,大大增加了學校的管理體制的負擔,管理信息系統已經進入高校,但還未普及,而對於學生成績管理來說,目前還沒有一套完整的,統一的系統。因此,開發一套適合、 兼容性好的系統是很有必要的。

1.2  研究意義

根據開發要求,學生成績管理系統全要應用於教育系統,完成對學生成績信息的計算機管理,使學院職員工輕工作壓力,同時,可以減少勞動力的使用,加快查詢速度、加強管理,加快國家和部門關於信息化的步伐,使管理更加規範化。學生成績管理系統是時代發展的必然產物。

2. 需求分析

編寫一個學生成績管理系統,每個學生信息包括:姓名、學號、C語言、編譯原理、數據庫以及離散數學的成績。具體功能如下:

(1)創建學生信息並以磁盤文件保存;

(2)讀取磁盤文件並顯示輸出所有學生的成績;

(3)按學號或姓名查詢成績;

(4)添加成績記錄;

(5)修改指定姓名或學號的學生的成績並可存盤;

(6)刪除指定姓名或學號的學生成績並可存盤;

(6)只顯示C語言成績60分以下、60~79、80~89、90分以上各分數段的學生信息;

(7)打印所有學生成績單。

3. 概要設計設計

3.1 功能模塊設計

功能模塊如下圖1所示:

                                                                                         圖1 功能模塊結構圖

3.2 主函數的流程設計

(1)主界面系統

  可分別輸入0—7數字來實現對學生信息的執行。各個按鍵的功能如下:

“0”:可退出程序;

“1”:錄入信息,調用input()函數;

“2”:查詢信息,先調用search()函數,根據姓名或學號分別調用xingming()和xuehao()函數;

“3”:修改信息,先調用modiway()函數,根據姓名或學號分別調用modify1 ()和modify2()函數;

“4”:添加學生信息,直接調用insert()函數;

“5”:刪除學生信息,先調用deleteway()函數,根據姓名或學號分別調用delete1 ()和delete2()函數;

“6”:顯示打印成績,直接調用print()函數;

“7”:統計C語言成績,直接調用count()函數。

 

4.  詳細設計和實施

4.1 主界面設計

(1)  功能介紹

本模塊主要是調用以上每個自定義函數,在界面中輸入相對應的數字便可進入相關模塊。保證了本程序的完美運行。

(2)  關鍵函數及其描述

void main()

{

    char ch;

    while(1)

    {

      menu();// 顯示菜單

      ch=getch();//選擇菜單

      if(ch=='0')

          break;

      switch(ch)//判斷功能項

      {

      case '1':input();break;

      case '2':search();break;

      case '3':modiway();break;

      case '4':insert();break;

      case '5':deleteway();break;

      case '6':print();break;

      case '7':count();break;

      }

    }

    printf("\n\n\n\t\t\t\tWelcome to use,Goodbye!\02!\n");

}

4.2 錄入信息

(1)功能簡介

該模塊主要實現學生信息的錄入。在界面中輸入“1 ”進入學生成績的錄入,錄入信息是一直到姓名爲“End”時結束錄入。

(2)流程圖

錄入信息模塊流程圖如圖2所示:

                                                                                  圖2 錄入信息

 

(3) 關鍵代碼及其描述

void input()

{

    FILE *fp;

    stu xs;           /*定義一個結構體變量來裝從文件中讀出來的數據*/

    if((fp=fopen("student.dat","ab"))==NULL)  //判斷文件能否打開

    {

       printf("can't open the file!\n");exit(0);     //正常退出

    }

    printf("\n錄入格式: 姓名 學號 C語言 編譯原理 數據庫 離散數學 \n");

    printf("當輸入姓名爲<End>結束錄入\n");

    while(1)                               

    {

        scanf("%s",xs.name);

        if(strcmp(xs.name,"End")==0) break; //判斷姓名是否爲END,用字符串判斷

        scanf("%d%f%f%f%f",&xs.num,&xs.c,&xs.by,&xs.sjk,&xs.lssx);

        fwrite(&xs,sizeof(stu),1,fp);        //將成績信息寫入文件

    }

    fclose(fp);

}

4.3 查詢信息

(1) 功能簡介

本模塊先定義了學生姓名和學號兩項信息,然後再自定義一個search函數,利用switch函數來通過這兩種方式來查詢。在界面中輸入“2”進入查詢信息模塊。接着輸入“1”則是按姓名查詢,輸入“2”則是按學號查詢。

(2)流程圖

查詢信息模塊流程圖如圖3所示:

 

                                                                                  圖3 查詢信息

(3) 關鍵代碼及其描述

void search()

{

       char ch1;

       system("cls");

    printf("請選擇何種方式查詢<編號>:\n");

    printf("1->姓名,2->學號:");

    ch1=getchar();              /*用字符接收*/

    switch(ch1)                 /*判斷*/

  {

    case '1':xingming();break;

    case '2':xuehao();break;

  }

getch(); 

4.4 修改信息

(1) 功能簡介

本模塊主要實現修改學生信息的功能,modify1和modify2分別定義兩種修改信息的方式,然後利用modiway函數,使用switch函數判斷選擇修改的方式,在界面中輸入“3”進入修改成績模塊,接着輸入“1”則是按姓名修改成績,輸入“2”則是按學號修改成績。

(2)流程圖

修改信息模塊流程圖如圖4所示:

                                                                                 圖4 修改信息

 

(3) 關鍵代碼及其描述

void modiway()

{

    char ch1;

    system("cls");

    printf("請輸入按何種方式修改<編號>:\n");

    printf("1->姓名,2->學號:");

    ch1=getchar();       /*用字符接收*/

    switch(ch1)          /*判斷*/

       {

      case '1':modify1();break;

      case '2':modify2();break;

       }

 

    getch();/*讓屏幕停留同時按任意鍵返回*/

}

4.5 添加學生

(1)功能簡介

本模塊主要實現了學生的添加,在界面中輸入“4”進入添加學生模塊,依次輸入姓名、學號、C語言,編譯原理,數據庫以及離散數學成績、和插入的位置。

(2)流程圖

添加學生模塊流程圖如圖5所示:

                                                                                 圖5 添加學生

 

(3) 關鍵代碼及其描述

void insert()

{

       int i=0,j,k,lenth;

    FILE *fp;

    stu s,xs[N];

    system("cls");

    printf("\n請輸入添加的學生的姓名:");

       scanf("%s",&s.name);

    printf("\n學生的學號:");scanf("%d",&s.num);

    printf("\n學生的成績:C語言、編譯原理、數據庫、離散數學:");scanf("%f %f %f %f",&s.c,&s.by,&s.sjk,&s.lssx);

    printf("\n請輸入插入到第幾行:");scanf("%d",&k);

    if((fp=fopen("student.dat","rb"))==NULL)

       {

           printf("can't open the file!\n");exit(0);

       }

    while(!feof(fp))

       {

        fread(&xs[i],sizeof(stu),1,fp);/*把數據讀入到結構體數組中*/

        if(feof(fp)) break;

        i++;

       }

    fclose(fp);

    lenth=i;                            //記錄此時lenth最大

    if(k<lenth && k>=0)                 /*k的位置要位於數組範圍之內*/

       {

       for(j=lenth-1;j>=k;j--)

           xs[j+1]=xs[j];               /*一開始j是最大的,往後移一個這樣移動避免數據被覆蓋*/

           xs[k]=s;                     /*將輸入的學生信息加入這個k位置*/

           lenth++;                   //增加一個學生空間,否則會少一個數據

       if((fp=fopen("student.dat","wb"))==NULL)

          {

               printf("不能建立文件!!\n");exit(0);

          }

       for(i=0;i<lenth;i++)

       fwrite(&xs[i],sizeof(stu),1,fp);  //存入數據

       }

    else/*不再數組範圍之內*/

       {

        if((fp=fopen("student.dat","ab"))==NULL)

              {

              printf("不能建立文件!!\n");exit(0);

              }

    fwrite(&s,sizeof(stu),1,fp);

       }

       fclose(fp);

}

4.6 刪除學生信息

(1) 功能介紹

根據學生的姓名或學號來刪除學生的信息,在主界面點擊“6”,接着選擇刪除學生信息的方式。

(2)刪除學生模塊流程圖如圖6所示:

                                                                                 圖6 刪除學生

(3) 關鍵代碼及其描述

//刪除:輸入學生學號,若該學生存在,則刪除,並顯示刪除後餘下的學生成績信息

void deleteway()

{

    char ch1;

    system("cls");

    printf("請輸入按何種方式刪除:\n");

    printf("1->姓名,2->學號:");

    ch1=getchar();/*用字符接收*/

    switch(ch1)/*判斷*/

       {

       case '1':delete1();break;

    case '2':delete2();break;

       }

       getch();/*讓屏幕停留同時按任意鍵返回*/

}

4.7 統計學生信息

(1) 功能介紹

本模塊主要實現了對學生成績的統計,對不同分數段的學生進行劃分並逐個顯示。在界面中輸入“6”,則進入統計學生信息模塊。按任意鍵退出。

(2)流程圖

統計學生模塊流程圖如圖7所示:

                                                                                圖7 統計學生

(3)  關鍵代碼及其描述

void count()

{

int i=0,j=0,k=0,l=0,m=0,n,p,q,r,t,u;

stu s[N], *p1[N],*p2[N],*p3[N],*p4[N];   /*用指針數組*/

fread(&s[i++],sizeof(stu),1,fp);         /*讀入數據*/

t=i;i=0;

for(u=0;u<t;u++)/*以下每個指針數組用於指向各分數段的學生信息*/

{

if(s[i].c<60) {p1[j++]=&s[i++];continue;

} /*每個學生信息只能位於一個分數段,各分數段都是如此*/

printf("不及格:姓名 學號 C語言\n");

printf("%10s %6d %6.2f\n",p1[n]->name,p1[n]->num,p1[n]->c}//顯示指針內的信息

//顯示不及格學生成績,各分數段都是如此

 

5.   測試數據與測試結果

5.1 系統測試

(1)主界面設計

具體效果如圖8所示。

 

                                                                               圖8 主函數界面

(2)學生成績信息錄入測試

學生成績錄入界面如圖9所示。

                                                                                  圖9 學生成績錄入

(3) 查詢信息系統測試

    可以通過姓名和學號兩種方式來查詢信息。圖10爲通過姓名來查詢,圖11爲通過學號來查詢。

                                                                               圖10姓名查詢

                                                                               圖11學號查詢

(4) 修改信息系統測試

     可以通過學生姓名和學號來修改信息,圖12爲通過姓名修改信息,圖13爲通過學號來修改信息。

                                                                               圖12 姓名修改

                                                                               圖13 學號修改

(5)添加學生系統測試

添加學生的界面如圖14所示。

                                                                               圖14 添加學生

(6)刪除學生信息系統測試

可以通過學生姓名和學號來刪除學生信息,圖15爲通過姓名修改信息,圖16爲按學號刪除學生信息。最終看下所剩下的學生信息,如圖17所示:

                                                                               圖15 按姓名刪除

                                                                               圖16按學號刪除

                                                                               圖17查詢刪除後的信息

 

 

(7)顯示成績系統測試

對添加、修改、刪除學生信息的所有學生成績單進行統計打印,具體如圖18所示:

                                                                               圖18 顯示打印成績

(8)統計成績系統截圖

     因爲C語言課程需要單獨統計學生成績情況,所以對學生C語言成績進行分類。具體的統計後界面如圖19所示。

                                                                               圖19 統計C語言

5.2 問題分析

1、編寫程序的過程中有很多問題,首先就是總的大體佈局,該如何構造函數,該構造哪些函數……解決的辦法其實也很簡單,大概看書上的學生信息管理系統的佈局,然後根據自己的構思在紙上簡單寫出來。最好先畫好流程圖,然後才慢慢地編寫程序。

2、接着就有很多小問題接踵而來,雖然這只是個小程序,但是運用的東西還真不少。整個程序中都需要定義文件指針,這就需要對文件指針的概念及運用有着深入的瞭解。這就需要看書了,具體的細節就需要百度來獲取了。例如while(!feof)就是讀取文件失敗的情況。還有fread和fwrite的格式。而且本程序中大部分都運用指針,對於指針的運用,還不能熟練的掌握,例如P1[i++]=&s[i++],將s[i++]賦值給指針P1,這就需要對指針的表示和指針所指向的內容要了解。

3、除了指針,還有struct結構體類型的定義。每一個地址對應必須要準確,稍不留意就會出錯。例如在printf()和scanf()中,後面的地址就容易出錯。尤其地址符&經常會忘。這就需要自己細心,反覆編譯查找出錯的地方。

4、另外,再錄入信息時,需要輸入一定的數據後中斷程序。一時不清楚如何解決,百度了一下。可以利用strcmp函數來檢查name是否與LAST一致,一致後就可以中斷程序。並且在使用strcmp函數時要注意字符要加引號,而引用的變量可不加。

5、還有就是如何保存修改後的學生的成績,之前無論如何都保存不了學生信息,後來查了百度,可以利用“fseek(fp,-sizeof(stu),1);fwrite(&xs,sizeof(stu),1,fp”,這就可以覆蓋之前的信息並顯示修改後的信息。

 

5.3 總結

通過本次實訓,我對C語言程序設計有了更深入的瞭解。雖然實訓的只有兩天,但是從上週我就開始考慮並設計程序了。C語言是真的有趣,複雜卻有條理的代碼是真的有意思。雖然免不了枯燥乏味,但是將程序編寫出來是非常有成就感的。本次實訓我選擇這個題目,就是因爲題目中包含C語言,想着如何將這個程序編好,作爲我學習C語言的結束的標誌。在編寫程序的過程中,當然陸陸續續地出現很多問題,出了參觀以下別人寫的程序外,還得專門百度來解決個別問題,這樣就可以深入地瞭解這個問題,處理起來就比較容易。尤其對文件有了更深入的瞭解。更重要的是,通過這次實訓,培養了自己的邏輯能力和獨立思考的能力,我想這個纔是最重要的。

 

 

參考文獻

[1] 陳珂,陳靜.實用C語言程序設計教程.中國電力出版社.2016.6

[2] 譚浩強.軟件工程導論[M].清華大學出版社,2013.6

[3] 姜仲秋. C語言程序設計.南京大學出版社,1998.1.

[4] K.N.King. C語言程序設計.人民郵電出版社.1998.2

 

參考源碼:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#define N 20
typedef struct
{
  char name[10];
  int num;
  float c;
  float by;
  float sjk;
  float lssx;
}stu;
void menu() 
{
   system("cls");  //清屏
   printf("\n\n\n\n\t\t\t*********   學生成績管理系統  ***********\n");
   printf("\t\t\t             Time:2020年6月6日              \n");       
   printf("\t\t\t|==========================================|\n");
   printf("\t\t\t|*************1.  錄入信息  ***************|\n");
   printf("\t\t\t|*************2.  查詢成績  ***************|\n");
   printf("\t\t\t|*************3.  修改信息  ***************|\n");
   printf("\t\t\t|*************4.  添加學生  ***************|\n");
   printf("\t\t\t|*************5.  刪除成績  ***************|\n");
   printf("\t\t\t|*************6.  顯示成績  ***************|\n");
   printf("\t\t\t|*************7.    統計    ***************|\n");
   printf("\t\t\t|*************0.    退出    ***************|\n");
   printf("\t\t\t|==========================================|\n");
   printf("\t\t\t|******************************************|\n");
   printf("\n\n\t\t\t      請選擇相應的功能<輸入編號>:");
}
//錄入信息

void input()
{
    FILE *fp;
    stu xs;                                   /*定義一個結構體變量來裝從文件中讀出來的數據*/
    if((fp=fopen("student.dat","ab"))==NULL)  //判斷文件能否打開
	{
	   printf("can't open the file!\n");exit(0);     //正常退出
	}
    printf("\n錄入格式: 姓名 學號 C語言 編譯原理 數據庫 離散數學 \n");
	printf("當輸入姓名爲<End>結束錄入\n");
    while(1)                                
	{
        scanf("%s",xs.name);
        if(strcmp(xs.name,"End")==0) break;   //判斷姓名是否爲LAST,用字符串判斷
        scanf("%d%f%f%f%f",&xs.num,&xs.c,&xs.by,&xs.sjk,&xs.lssx);
        fwrite(&xs,sizeof(stu),1,fp);        //將成績信息寫入文件
	}
    fclose(fp);
}
//姓名定義

void xingming()
{
    FILE *fp;
    stu xs;
    char name[10];
    printf("\n請輸入需要查詢的學生姓名: ");
	scanf("%s",name);
    if((fp=fopen("student.dat","rb"))==NULL) 
	{
	   printf("can't open the file!\n");exit(0);
	}
    while(!feof(fp))                           //判斷文件是否到達末尾,即讀取文件失敗時
	{
        fread(&xs,sizeof(stu),1,fp);
        if(strcmp(xs.name,name)==0)//按姓名查詢時判斷輸入的姓名是否存在,會循環從數據中找取
		{
           printf(" 學生的信息如下:\n");
           printf("\n%10s %6s %6s %6s %6s %6s \n","姓名","學號","C語言","編譯原理","數據庫","離散數學");
           printf("%10s %6d %6.2f %6.2f   %6.2f  %6.2f \n",xs.name,xs.num,xs.c,xs.by,xs.sjk,xs.lssx);
           break;
		}
	}
    if(feof(fp))
		printf("ERROR,查找失敗!!!"); /*學生不存在*/
    fclose(fp);
}

//學號定義

void xuehao()
{
    FILE *fp;
    stu xs;
    int num;
    printf("\n請輸入需要查詢的學生學號: ");
	scanf("%d",&num);
    if((fp=fopen("student.dat","rb"))==NULL)
	{
	    printf("can't open the file");exit(0);
	}
    while(!feof(fp))
	{
        fread(&xs,sizeof(stu),1,fp);
        if(xs.num==num)/*按學號查詢時判斷輸入的學號是否存在,會循環從數據中找取*/
		{
             printf(" 學生的信息如下:\n");
           printf("\n%10s %6s %6s %6s %6s %6s \n","姓名","學號","C語言","編譯原理","數據庫","離散數學");
           printf("%10s %6d %6.2f %6.2f   %6.2f   %6.2f \n",xs.name,xs.num,xs.c,xs.by,xs.sjk,xs.lssx);
             break;
		}
	}
     if(feof(fp)) 
		 printf("ERROR,查找失敗!!!");
     fclose(fp);
}

//查詢

void search()
{
	char ch1;
	system("cls");
    printf("請選擇何種方式查詢<編號>:\n");
    printf("1->姓名,2->學號:");
    ch1=getchar();              /*用字符接收*/
    switch(ch1)                 /*判斷*/
  {
    case '1':xingming();break;
    case '2':xuehao();break;
  }
getch();                       /*讓屏幕停留同時按任意鍵返回*/ }

//修改:輸入學生的姓名,查找該學生,若找到則修改該生的成績信息,並顯示修改前後的結果;

void modify1()
{

    stu xs;
    FILE *fp;
    char name[10];
    printf("\n請輸入要修改的學生姓名: ");
	scanf("%s",name);
    if((fp=fopen("student.dat","rb+"))==NULL)
	{
     	printf("can't open the file!\n");exit(0);
	}
    while(!feof(fp))
	{
         fread(&xs,sizeof(stu),1,fp);
         if(strcmp(xs.name,name)==0)                      /*判斷輸入要修改的姓名是否存在*/
		 {
            printf(" 修改前學生的信息:\n");
            printf("\n%10s %6s %6s %6s %6s %6s \n","姓名","學號","C語言","編譯原理","數據庫","離散數學");
            printf("%10s %6d %6.2f %6.2f  %6.2f  %6.2f \n",xs.name,xs.num,xs.c,xs.by,xs.sjk,xs.lssx);
            printf("\n請依次輸入 C語言 編譯原理 數據庫 離散數學的成績:");
			scanf("%f%f%f%f",&xs.c,&xs.by,&xs.sjk,&xs.lssx);
            break;
		 }
	}
    if(!feof(fp))
	{
         printf(" \n 修改後的學生的信息如下:\n");
         printf("\n%10s %6s %6s %6s %6s %6s \n","姓名","學號","C語言","編譯原理","數據庫","離散數學");
         printf("%10s %6d %6.2f %6.2f  %6.2f  %6.2f \n",xs.name,xs.num,xs.c,xs.by,xs.sjk,xs.lssx);
		 fseek(fp,-sizeof(stu),1);   //負號表示後退,1表示文件當前位置
		 fwrite(&xs,sizeof(stu),1,fp);  //再重新寫入,同時把之前的要修改的覆蓋掉
	}
    else
         printf("\nERROR,學生不存在,修改失敗!!");
    fclose(fp);
	getch();
    
}

//修改:輸入學生的學號,查找該學生,若找到則修改該生的成績信息,並顯示修改前後的結果;

void modify2()
{
    stu xs;
    FILE *fp;
    int num;
    printf("\n請輸入要修改的學生學號: ");
	scanf("%d",&num);
    if((fp=fopen("student.dat","rb+"))==NULL)
	{
	    printf("can't open the file!\n");exit(0);
	}

    while(!feof(fp))
	{
       fread(&xs,sizeof(stu),1,fp);
         if(xs.num==num)/*判斷輸入要修改的姓名是否存在*/
		 {
            printf(" 修改前學生的信息如下:\n");
            printf("\n%10s %6s %6s %6s %6s %6s \n","姓名","學號","C語言","編譯原理","數據庫","離散數學");
            printf("%10s %6d %6.2f %6.2f  %6.2f  %6.2f \n",xs.name,xs.num,xs.c,xs.by,xs.sjk,xs.lssx);
            printf("\n請依次輸入C語言 編譯原理 數據庫以及離散數學的成績:");
			scanf("%f%f%f%f",&xs.c,&xs.by,&xs.sjk,&xs.lssx);
            break;
		 }
	}
    if(!feof(fp))
	{
        printf(" \n 修改後的學生的信息如下:\n");
         printf("\n%10s %6s %6s %6s %6s %6s \n","姓名","學號","C語言","編譯原理","數據庫","離散數學");
         printf("%10s %6d %6.2f %6.2f  %6.2f  %6.2f \n",xs.name,xs.num,xs.c,xs.by,xs.sjk,xs.lssx);
		fseek(fp,-sizeof(stu),1);
		fwrite(&xs,sizeof(stu),1,fp);
	}
    else
        printf("\nERROR,學生不存在,修改失敗!!");
	getch();
    fclose(fp);
    
}
//選擇修改方式
void modiway()
{
    char ch1;
    system("cls");
    printf("請輸入按何種方式修改<編號>:\n");
    printf("1->姓名,2->學號:");
    ch1=getchar();       /*用字符接收*/
    switch(ch1)          /*判斷*/
	{
      case '1':modify1();break;
      case '2':modify2();break;
	}

    getch();/*讓屏幕停留同時按任意鍵返回*/ 
}

//插入:輸入學生的平時的各項成績,插入到指定位置;當指定的位置超出範圍時,將其插入到全班的最後,並顯示插入成功後的結果
void insert()
{
	int i=0,j,k,lenth;
    FILE *fp;
    stu s,xs[N];
    system("cls");
    printf("\n請輸入添加的學生的姓名:");
	scanf("%s",&s.name);
    printf("\n學生的學號:");scanf("%d",&s.num);
    printf("\n學生的成績:C語言、編譯原理、數據庫、離散數學:");scanf("%f %f %f %f",&s.c,&s.by,&s.sjk,&s.lssx);
    printf("\n請輸入插入到第幾行:");scanf("%d",&k); 
    if((fp=fopen("student.dat","rb"))==NULL)
	{
	    printf("can't open the file!\n");exit(0);
	}
    while(!feof(fp))
	{
        fread(&xs[i],sizeof(stu),1,fp);/*把數據讀入到結構體數組中*/
        if(feof(fp)) break;
        i++;
	}
    fclose(fp);
    lenth=i;                            //記錄此時lenth最大
    if(k<lenth && k>=0)                 /*k的位置要位於數組範圍之內*/
	{
       for(j=lenth-1;j>=k;j--)
           xs[j+1]=xs[j];               /*一開始j是最大的,往後移一個這樣移動避免數據被覆蓋*/
           xs[k]=s;                     /*將輸入的學生信息加入這個k位置*/
           lenth++;                   //增加一個學生空間,否則會少一個數據
       if((fp=fopen("student.dat","wb"))==NULL)
	   {
	        printf("不能建立文件!!\n");exit(0);
	   }
       for(i=0;i<lenth;i++)
       fwrite(&xs[i],sizeof(stu),1,fp);  //存入數據
	}
    else/*不再數組範圍之內*/
	{
        if((fp=fopen("student.dat","ab"))==NULL) 
		{
	       printf("不能建立文件!!\n");exit(0);
		}
    fwrite(&s,sizeof(stu),1,fp);
	}
	fclose(fp);
}

//顯示

void print()
{
    FILE *fp;
    stu s;
    system("cls");
    if((fp=fopen("student.dat","rb"))==NULL)
	{
	    printf("can't open the file!\n");exit(0);
	}
    printf("\n%10s %s %6s %6s %6s %6s \n","姓名","學號","C語言","編譯原理","數據庫","離散數學");
    while(!feof(fp))
	{
        fread(&s,sizeof(stu),1,fp);  //從文件中讀取成績信息
           if(feof(fp)) break;       //判斷是否文件尾
              printf("%10s %4d %6.2f %6.2f  %6.2f  %6.2f \n",s.name,s.num,s.c,s.by,s.sjk,s.lssx);
	}
    fclose(fp);
    getch();
}

//刪除:輸入學生姓名,若該學生存在,則刪除,並顯示刪除後餘下的學生成績信息

void delete1()
{

    stu xs[N];
    FILE *fp;
    char name[10];
    int i=0,len,k=-1/*k<0是爲後面if判斷用的*/;
    system("cls");
    printf("\n請輸入要刪除的學生姓名: ");scanf("%s",name);
    if((fp=fopen("student.dat","rb+"))==NULL) 
	{
	    printf("can't open the file!\n");exit(0);
	}
    while(!feof(fp))
	{
       fread(&xs[i],sizeof(stu),1,fp);
       if(feof(fp)) break;
       if(strcmp(xs[i].name,name)==0) k=i;
       i++;
	}
    fclose(fp);

//以下是刪除後重新寫文件

    len=i;/*結構體數組上限*/
    if(k>=0)/*k>0說明找到刪除學生位置*/
	{
      if((fp=fopen("student.dat","wb+"))==NULL) 
	  {
	      printf("can't open the file!\n");exit(0);
	  }
      for(i=0;i<len;i++)
	  {
      if(i==k) continue;/*從這個位置開始寫入*/
      fwrite(&xs[i],sizeof(stu),1,fp);
	  }
      fclose(fp);
	}
      else {printf("ERROR,刪除失敗!!!\n");getch();} /*失敗後重新返回菜單*/
      print();
}


//刪除:輸入學生學號,若該學生存在,則刪除,並顯示刪除後餘下的學生成績信息

void delete2()
{
    stu xs[N];
    FILE *fp;
    int num;
    int i=0,len,k=-1/*k<0是爲後面if判斷用的*/;
    system("cls");
    printf("\n請輸入要刪除的學生學號: ");
	scanf("%d",&num);
    if((fp=fopen("student.dat","rb+"))==NULL) 
	{
	printf("can't open the file!\n");exit(0);
	}
    while(!feof(fp))
	{
        fread(&xs[i],sizeof(stu),1,fp);
        if(feof(fp)) break;
        if(xs[i].num==num)
			k=i;
            i++;
	}
    fclose(fp);
//以下是刪除後重新寫文件

    len=i;/*結構體數組上限*/
    if(k>=0)/*k>0說明找到刪除學生位置*/
	{
    if((fp=fopen("student.dat","wb+"))==NULL) 
	{
	     printf("can't openfile!\n");exit(0);
	}
    for(i=0;i<len;i++)
	{
       if(i==k) continue;/*從這個位置開始寫入*/
       fwrite(&xs[i],sizeof(stu),1,fp);
	}
    fclose(fp);
	}
    else {printf("ERROR,刪除失敗!!!\n");getch();} /*失敗後重新返回菜單*/
    print();
}


//刪除

void deleteway()
{
    char ch1;
    system("cls");
    printf("請輸入按何種方式刪除:\n");
    printf("1->姓名,2->學號:");
    ch1=getchar();/*用字符接收*/
    switch(ch1)/*判斷*/
	{
	case '1':delete1();break;
    case '2':delete2();break;
	}
	getch();/*讓屏幕停留同時按任意鍵返回*/
}

//統計C語言成績情況

void count() 
{
    int i=0,j=0,k=0,l=0,m=0,n,p,q,r,t,u;   //j,k,m,l分別是指各個分數段,n,p,q,r也是
    FILE *fp;
    stu s[N], *p1[N],*p2[N],*p3[N],*p4[N];/*用指針數組*/
    system("cls");
    if((fp=fopen("student.dat","rb"))==NULL)
	{
	    printf("can't open the file!\n");exit(0);
	}
    while(!feof(fp))
	{
        fread(&s[i++],sizeof(stu),1,fp);/*讀入數據*/
        if(feof(fp)) break;  //到文件末尾中斷程序
	}
    t=i;i=0;           //t 指最大
    for(u=0;u<t;u++)/*以下每個指針數組用於指向各分數段的學生信息*/
	{
        if(s[i].c<60) 
		{
			p1[j++]=&s[i++];continue;
		}                                     /*每個學生信息只能位於一個分數段*/
        if(s[i].c>=60 && s[i].c<80) 
		{
			p2[k++]=&s[i++];continue;
		}
        if(s[i].c>=80 && s[i].c<90) 
		{
			p3[l++]=&s[i++];continue;
		}
        if(s[i].c>=90)
		{
			p4[m++]=&s[i++];continue;
		}
	}
    printf("     不及格:姓名 學號 C語言\n");
    for(n=0;n<j-1;n++)
	{
        printf("%14s %4d %6.2f\n",p1[n]->name,p1[n]->num,p1[n]->c);      //逐個顯示個分數段信息,顯示上面指針的內容
	}
    printf(" 60-79分之間:姓名 學號 C語言\n");
    for(p=0;p<k;p++)
	{
        printf("%16s %4d %6.2f\n",p2[p]->name,p2[p]->num,p2[p]->c);
	}
    printf(" 80-89分之間:姓名 學號 C語言\n");
    for(q=0;q<l;q++)
	{
        printf("%16s %4d %6.2f\n",p3[q]->name,p3[q]->num,p3[q]->c);
	}
    printf("90以上:姓名 學號 C語言\n");
    for(r=0;r<m;r++)
	{
        printf("%12s %4d %6.2f\n",p4[r]->name,p4[r]->num,p4[r]->c);
	}
    fclose(fp);
    getch();
}


//菜單選擇

void main()
{
	char ch;
    while(1)
	{
      menu();// 顯示菜單
      ch=getch();//選擇菜單
      if(ch=='0') 
		  break;
      switch(ch)//判斷功能項
	  {
      case '1':input();break;
      case '2':search();break;
      case '3':modiway();break;
      case '4':insert();break;
	  case '5':deleteway();break;
      case '6':print();break;
	  case '7':count();break;
	  }
	} 
	printf("\n\n\n\t\t\t\tWelcome to use,Goodbye!\02!\n");
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章