主頁 > 軟體設計 > BFU《高校教師工資管理系統》課程設計

BFU《高校教師工資管理系統》課程設計

2021-01-03 10:35:49 軟體設計

北 京 林 業 大 學

2020學年—2021學年第1學期 程式設計基礎課程設計 實習報告書

實習內容: 高校教師工資管理系統

實習環境: Sublime Text 3

目錄

一、實習步驟

二、實作方法概述

三、技術方案實作

3.0 資料存盤結構

3.0.0本地存盤結構(**創新點**)

3.0.1 教師資訊結構體 及 學院職稱映射陣列

3.0.2 薪資資訊結構體

3.0.3 學院平均值統計結構體 與 職稱平均值統計結構體

3.1 Operation Functions 概述

3.2 Check Functions 概述

3.2.1 checkten()--對輸入的數字范圍進行檢測

3.2.2 checkdb()--檢測用戶輸入是否為實數

3.2.3 checkid()--檢測用戶輸入id是否合法且合規

3.2.4 checkname()--檢測用戶名字是否存在

3.2.5 checkmon()--用以檢測所要查詢的月份是否存在salary資訊中

3.3 Storage Functions 概述

3.3.1 inpter() inpsal()--ter輸入函式 與 sal輸入函式

3.3.2 delter() delsal()--洗掉教師資訊及薪資資訊

3.3.3 自定義簡便SQL操作

3.4 Algorithm Functions 概述

3.4.1 showter()--可選mode的教師資訊串列列印函式

3.4.2 searchterid() searchsalid()--尋找所傳id對應的實際索引以便后續操作

3.4.3 swapter()swapsal()swapcol()swapjob()--交換函式

3.4.4 sortter_id() sortsal_id()--排序函式

3.4.5 calcolavg_sort() caljobavg_sort()--實作統計分析排序功能的函式

3.4.6 FreshSalName()--同步sal與ter之間的資訊

四、結果展示:

4.0開始界面

4.1進入錄入資料并保存功能

4.1.1教師資訊錄入功能

4.1.2錄入教師工資資訊

4.1.3 保存到本地功能

4.2 進入修改資料并保存功能

4.2.1 根據工號修改某位教師的基本資訊和工資資訊

4.2.2 根據姓名修改某位教師的基本資訊和工資資訊

4.2.3 洗掉某一工號的教師的所有資訊

4.3查詢顯示功能

4.3.1展示所有教師的基本資訊

4.3.2根據月份顯示所有教師當月工資資訊(以工號為序)

4.3.3根據工號查詢某位教師某一月份的基本資訊和工資資訊

4.3.4根據姓名查詢某位教師某一月份的基本資訊和工資資訊

4.4統計分析

4.4.1根據月份,統計不同學院教師的平均應發工資和平均實發工資

4.4.2根據月份,統計不同職稱教師的平均應發工資和平均實發工資

4.5從本地匯入資料(**創新點**)

4.6保存并退出功能

五、結束語:

一、實習步驟:

我于第一天進行該專案的整體分析及技術方案的選擇,第二天進行該程式的編碼作業,第三天進行程式的測驗作業和報告的書寫作業,

二、實作方法概述:

根據要求,該程式完全基于C語言實作,未使用任何外部庫檔案,代碼全部手敲完成,無任何借鑒復制行為,且撰寫代碼的全程序已錄制視頻,并將快放版上傳至B站:其地址為:https://www.bilibili.com/video/BV1Af4y1e7Tc/

該程式按照實驗要求分為五大模塊,完全實作實驗要求的所有功能,存盤在程式內采用結構體的方式,由于禁止使用SQL庫函式,所以我自己手寫了一套簡化版的SQL生成與決議函式,用于程式在本地的存盤結構(可實作對之前資料,或樣例資料的匯入),

設計采用自頂向下的方式,將每個大問題細化為各個小問題,將需要重復用到的解決方案演算法生成為可選擇模式的函式(如4.0.1 showter()),以達到簡化代碼量且提高可移植性的目標,每完成一個小模塊便進行測驗,以確保程式的正確性,

本系統系統功能結構

三、技術方案實作:

該程式的函式功能分為四大模塊,接下來將一一介紹,

3.0 資料存盤結構

3.0.0本地存盤結構(**創新點**)

由于該專案禁止使用SQL資料庫的相關庫檔案,我自己寫了一套類似于SQL存盤結構的生成函式及解釋函式,其于本地存盤的樣式類似于SQL中的insert values()陳述句,

  1. (0000000001,wu zheng,3,2)
  2. (0000000003,qian,3,2)
  3. (0000000001,wu zheng,3,2,2,200.00,100.00,56.00,300.00,244.00)
  4. (0000000001,wu zheng,3,2,3,45.00,6.00,6.00,51.00,45.00)

接下來將首先介紹該簡化SQL的生成方法

  1. void savetolocter()
  2. {
  3. // (id,name,colid,jobid)
  4. FILE * f1;
  5. f1=fopen("terdata.dat","w+");
  6. if(f1==NULL){printf("save to local unaviliable\n");return;}
  7. int i;
  8. for(i=0;i<tercnt;i++)
  9. {
  10. char tline[101]="(", tnum[5];
  11. strcat(tline,ter[i].id);
  12. strcat(tline,",");
  13. strcat(tline,ter[i].name);
  14. strcat(tline,",");
  15. strcat(tline,itoa(ter[i].collegeid,tnum,10));
  16. strcat(tline,",");
  17. strcat(tline,itoa(ter[i].jobid,tnum,10));
  18. strcat(tline,")");
  19. fprintf(f1, "%s\n", tline);
  20. }
  21. fclose(f1);
  22. }
  23. void savetolocsal()
  24. {
  25. FILE * f1;
  26. f1=fopen("saldata.dat","w+");
  27. if(f1==NULL){printf("save to local unaviliable\n");return;}
  28. int i;
  29. for(i=0;i<salcnt;i++)
  30. {
  31. char tline[201]="(", tnum[12];
  32. strcat(tline,sal[i].id);
  33. strcat(tline,",");
  34. strcat(tline,sal[i].name);
  35. strcat(tline,",");
  36. strcat(tline,itoa(sal[i].collegeid,tnum,10));
  37. strcat(tline,",");
  38. strcat(tline,itoa(sal[i].jobid,tnum,10));
  39. strcat(tline,",");
  40. strcat(tline,itoa(sal[i].month,tnum,10));
  41. strcat(tline,",");
  42. strcat(tline,d2s(sal[i].basicsal,tnum));
  43. strcat(tline,",");
  44. strcat(tline,d2s(sal[i].addsal,tnum));
  45. strcat(tline,",");
  46. strcat(tline,d2s(sal[i].subsal,tnum));
  47. strcat(tline,",");
  48. strcat(tline,d2s(sal[i].theosal,tnum));
  49. strcat(tline,",");
  50. strcat(tline,d2s(sal[i].truesal,tnum));
  51. strcat(tline,")");
  52. fprintf(f1, "%s\n", tline);
  53. }
  54. fclose(f1);
  55. }

其核心思想為模擬SQL的資料以逗號為分割的方式,將資料行通過fprintf結構化的存入到檔案中,以便后續的讀取,

接下來將介紹該SQL陳述句的決議函式

  1. void loadlocter(char * loc)
  2. {
  3. FILE * f1;
  4. f1=fopen(loc,"r");
  5. if(f1==NULL){printf("load to here unaviliable\n");return;}
  6. tercnt=0;
  7. char tinp[100];
  8. while(fgets(tinp,300,f1)!=NULL && tinp[0]!=10)
  9. {
  10. char tid[11],tna[31];
  11. int tcd,tjd;
  12. int i;
  13. for(i=1;i<=10;i++) tid[i-1]=tinp[i];
  14. int tcnt=0;
  15. for(i=12;tinp[i]!=',';i++) tna[tcnt++]=tinp[i];
  16. tna[tcnt]='\0';
  17. tcd=atoi(&tinp[i+1]);
  18. tjd=atoi(&tinp[i+3]);
  19. strcpy(ter[tercnt].id,tid);
  20. strcpy(ter[tercnt].name,tna);
  21. ter[tercnt].collegeid=tcd;
  22. ter[tercnt].jobid=tjd;
  23. tercnt++;
  24. //(1234567890,de d,1,1)
  25. }
  26. fclose(f1);
  27. sortter_id();
  28. }
  29. void loadlocsal(char * loc)
  30. {
  31. FILE * f1;
  32. f1=fopen(loc,"r");
  33. if(f1==NULL){printf("load to here unaviliable\n");return;}
  34. salcnt=0;
  35. char tinp[200];
  36. while(fgets(tinp,300,f1)!=NULL && tinp[0]!=10)
  37. {
  38. char tid[11],tna[31];
  39. int tcd,tjd;
  40. double t1,t2,t3,t4,t5;
  41. int i;
  42. for(i=1;i<=10;i++) tid[i-1]=tinp[i];
  43. int tcnt=0;
  44. for(i=12;tinp[i]!=',';i++) tna[tcnt++]=tinp[i];
  45. tna[tcnt]='\0';
  46. tcd=atoi(&tinp[++i]);i++;
  47. tjd=atoi(&tinp[++i]);i+=2;
  48. char tmon[4];tcnt=0;
  49. for(;tinp[i]!=',';i++) tmon[tcnt++]=tinp[i];
  50. tmon[tcnt]='\0';
  51. int mon=atoi(tmon);
  52. char tc[15];tcnt=0;
  53. for(i++;tinp[i]!=',';i++) tc[tcnt++]=tinp[i];
  54. tc[tcnt]='\0';t1=atof(tc);tcnt=0;
  55. for(i++;tinp[i]!=',';i++) tc[tcnt++]=tinp[i];
  56. tc[tcnt]='\0';t2=atof(tc);tcnt=0;
  57. for(i++;tinp[i]!=',';i++) tc[tcnt++]=tinp[i];
  58. tc[tcnt]='\0';t3=atof(tc);tcnt=0;
  59. for(i++;tinp[i]!=',';i++) tc[tcnt++]=tinp[i];
  60. tc[tcnt]='\0';t4=atof(tc);tcnt=0;
  61. for(i++;tinp[i]!=')';i++) tc[tcnt++]=tinp[i];
  62. tc[tcnt]='\0';t5=atof(tc);tcnt=0;
  63. strcpy(sal[salcnt].id,tid);
  64. strcpy(sal[salcnt].name,tna);
  65. sal[salcnt].collegeid=tcd;
  66. sal[salcnt].jobid=tjd;
  67. sal[salcnt].month=mon;
  68. sal[salcnt].basicsal=t1;
  69. sal[salcnt].addsal=t2;
  70. sal[salcnt].subsal=t3;
  71. sal[salcnt].theosal=t4;
  72. sal[salcnt].truesal=t5;
  73. salcnt++;
  74. }
  75. fclose(f1);
  76. }

其核心為檢測逗號所在位置,并以逗號為分割符,進行資料型別的轉換操作,最后復制到相應的變數中,

3.0.1 教師資訊結構體 及 學院職稱映射陣列

  1. struct Teacher{
  2. char id[11];
  3. char name[31];
  4. int collegeid;
  5. int jobid;
  6. }ter[NTer],tmpt; // use tmp to change
  7. int tercnt=0; // count the number of all teacher
  8. char col_sec[Ncol+1][31]={"","Information","Engineer","Theory","Arts","Biology"}; // college nubmer to name
  9. char job_sec[Njob+1][31]={"","Professor","Ass-Professor","Teacher","Tutor"}; // job nubmer to name

該段特殊采用數字映射字串的方法,將學院職稱皆量化為int,方便后續的操作,

3.0.2 薪資資訊結構體

  1. struct Salary{
  2. char id[11];
  3. char name[31];
  4. int collegeid;
  5. int jobid;
  6. int month;
  7. double basicsal, addsal, subsal, theosal, truesal;
  8. }sal[Nsal],tmps;
  9. int salcnt=0; // count the number of all records

basicsal—基本工資,addsal—業績津貼,subsal—扣除費用,theosal—應發工資,truesal—實發工資,

3.0.3 學院平均值統計結構體 與 職稱平均值統計結構體

  1. struct College
  2. {
  3. int collegeid;
  4. double thavg,travg;
  5. }col[6],tmpc;
  6. struct Job
  7. {
  8. int jobid;
  9. double thavg,travg;
  10. }job[6],tmpj;

進行統計分析時使用,

3.1 Operation Functions 概述

該部分代碼實作了程式與外接互動的全部功能,負責讀取用戶的操作輸入,并與用戶進行互動, 該部分具體內容將在【四】中進行演示并介紹,

3.2 Check Functions 概述

該部分代碼對實作程式魯棒性檢測及排除起到了重要作用,下面將依次介紹其實作方案,

3.2.1 checkten()--對輸入的數字范圍進行檢測

(應用于用戶選單選擇等)

  1. int checkten(int L,int R)
  2. {
  3. char opeinp[20];
  4. scanf("%s",opeinp);
  5. while ((atoi(opeinp)) == 0 or (atoi(opeinp)) > R or (atoi(opeinp)) < L )
  6. {
  7. printf("your input is invalid,please input again(just number from %d to %d):____\b\b\b",L,R);
  8. scanf("%s",opeinp);
  9. }
  10. return atoi(opeinp);
  11. }

通過atoi函式實作輸入字串向int型別的轉換作業,并判斷其大小范圍是否在給定的[L,R]區間內,如果非數字,或非所需區間,則給出提示并反復要求用戶輸入,直至用戶輸入合法,回傳該數值,

3.2.2 checkdb()--檢測用戶輸入是否為實數

(用于工資輸入的魯棒性檢查)

  1. double checkdb()
  2. {
  3. char opeinp[20];
  4. scanf("%s",opeinp);
  5. while ((atof(opeinp)) == 0)
  6. {
  7. printf("your input is invalid,please input again(just a real number):________\b\b\b\b\b\b\b\b");
  8. scanf("%s",opeinp);
  9. }
  10. return atof(opeinp);
  11. }

通過atof函式,將輸入字串轉換為double型別,如若轉換失敗(atof回傳值為0),則給出提示并反復要求用戶輸入,直至用戶輸入合法,回傳該數值,

3.2.3 checkid()--檢測用戶輸入id是否合法且合規

(用于id輸入的魯棒性檢查)

  1. void checkid(char * inpid, int judgeexist)
  2. {// if judgeexist == 1 , until input exist then return;
  3. // if judgeexist == 2 , until input not exist return;
  4. while(scanf("%s",inpid))
  5. {
  6. if(inpid[10] != '\0')
  7. { // check 10 digit to stop
  8. printf("your ID format is invalid,please make sure it is consist of 10 nubmers,ID:__________\b\b\b\b\b\b\b\b\b\b");
  9. continue;
  10. }
  11. int i;
  12. for(i = 0; i < 10; i++)
  13. {
  14. if(inpid[i] > '9' or inpid[0] < '0')
  15. {
  16. printf("your ID format is invalid,please make sure it is consist of 10 nubmers,ID:__________\b\b\b\b\b\b\b\b\b\b");
  17. break;
  18. }
  19. }
  20. if(i==10)
  21. { // format valid
  22. // to check existence
  23. int f=0; // 0 not exist; 1 exist
  24. for(i = 0;i < tercnt; i++)
  25. {
  26. if(strcmp(ter[i].id, inpid) == 0)
  27. {
  28. f=1;
  29. //printf("your ID input is existed, please make sure it's new one's id,ID:__________\b\b\b\b\b\b\b\b\b\b");
  30. break;
  31. }
  32. }
  33. if(judgeexist==1)
  34. {
  35. if(f==0)
  36. {
  37. printf("your ID input is not existed, please make sure it's above one's id,ID:__________\b\b\b\b\b\b\b\b\b\b");
  38. continue;
  39. }
  40. if(f==1)
  41. {
  42. return ;
  43. }
  44. }
  45. if(judgeexist==2)
  46. {
  47. if(f==1)
  48. {
  49. printf("your ID input is existed, please make sure it's new one's id,ID:__________\b\b\b\b\b\b\b\b\b\b");
  50. continue;
  51. }
  52. if(f==0)
  53. {
  54. return ;
  55. }
  56. }
  57. }
  58. }
  59. return ; // no use,just done for warning
  60. }

該函式6-10行判斷輸入是否為10位,10位判斷合法后,進入每位是否為數字的判斷,再次合法后,才將進入可選mode的判斷,

該函式我設定為可選mode,如果judgeexist == 1 ,則直到所輸入id存在于系統中才會回傳,如果judgeexist == 1 ,則直到所輸入id是不事先存在的才會回傳,該實作有利于后續的實際操作

3.2.4 checkname()--檢測用戶名字是否存在

(用于檢索名字時的魯棒性檢測)

  1. int checkname(char * inpname)
  2. {
  3. int t=0;
  4. rewind(stdin);
  5. while(1)
  6. {
  7. gets(inpname);
  8. rewind(stdin);
  9. int i;
  10. for(i=0;i<tercnt;i++)
  11. {
  12. if(strcmp(ter[i].name,inpname) == 0)
  13. {
  14. return 1;
  15. }
  16. }
  17. printf("your name input is not existed, please make sure it's above one's name,NAME:__________\b\b\b\b\b\b\b\b\b\b");
  18. t++;
  19. if(t==5) break;
  20. }
  21. return 0;
  22. }

該函式將遍歷整個ter結構體內的所有name,直至有匹配才回傳,如若一直未匹配,則證明不存在該名字,故提示用戶重新輸入,

3.2.5 checkmon()--用以檢測所要查詢的月份是否存在salary資訊中

  1. int checkmon(int * mon,char * id)
  2. {
  3. int t=1; // tried too many times
  4. while(1)
  5. {
  6. t++;
  7. if(searchsalid(id,*mon)!=-1) return 1;
  8. printf("%d month do not have salary information\n",*mon);
  9. printf("please resure and then INPUT:_____\b\b\b");
  10. *mon=checkten(1,12);
  11. if(t==5) break;
  12. }
  13. return 0;
  14. }

通過呼叫searchsalid 并進行匹配實作(后續將介紹該函式)

3.3 Storage Functions 概述

這些函式實作了資料的錄入,修改,洗掉,以及本地化SQL存盤等功能,

接下來將一一介紹,

3.3.1 inpter() inpsal()--ter輸入函式 與 sal輸入函式

  1. void inpter(int tid,int notfirst)
  2. {
  3. printf("Input the Teacher's NAME:______________\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
  4. rewind(stdin);
  5. gets(ter[tid].name); // to ignored the sperate by space
  6. printf("Input the college index of the teacher:\n1.Information,2.Engineer,3.Theory,4.Art,5.Biology. INPUT:___\b\b");
  7. ter[tid].collegeid=checkten(1,5);
  8. printf("Input the job index of the teacher:\n1.Professor,2.Ass-Professor,3.Teacher,4.Tutor. INPUT:___\b\b");
  9. ter[tid].jobid=checkten(1,4);
  10. struct Salary * sa;
  11. for(sa=sal;sa<sal+salcnt;sa++)
  12. {
  13. if(strcmp(sa->id,ter[tid].id)==0)
  14. {
  15. strcpy(sa->name,ter[tid].name);
  16. sa->jobid = ter[tid].jobid;
  17. sa->collegeid = ter[tid].collegeid;
  18. }
  19. }
  20. if(notfirst == 0) tercnt++;
  21. showter(3,ter[tid].id);
  22. if(notfirst == 0) tercnt--;
  23. printf("BELOW INFORMATION SAVED SUCCESSFULly \n");
  24. printf("PRESS ENTER TO CONTINUE.\n");getchar();getchar();
  25. }
  26. void inpsal(int sid,int notfirst)
  27. {
  28. printf("please input the month(nubmer from 1 to 12):______\b\b\b");
  29. sal[sid].month=checkten(1,12);
  30. printf("please input the basic salary:________\b\b\b\b\b\b\b\b");
  31. sal[sid].basicsal=checkdb();
  32. printf("please input the additional salary:________\b\b\b\b\b\b\b\b");
  33. sal[sid].addsal=checkdb();
  34. printf("please input the subtract salary:________\b\b\b\b\b\b\b\b");
  35. sal[sid].subsal=checkdb();
  36. sal[sid].theosal=sal[sid].basicsal+sal[sid].addsal;
  37. sal[sid].truesal=sal[sid].theosal-sal[sid].subsal;
  38. FreshSalName(sid);
  39. if(notfirst == 0) salcnt++;
  40. showsal(3,sal[sid].id,sal[sid].month);
  41. if(notfirst == 0) salcnt--;
  42. printf("BELOW INFORMATION SAVED SUCCESSFULlY \n");
  43. printf("PRESS ENTER TO CONTINUE.\n");getchar();getchar();
  44. }

該段代碼實作了排除魯棒性的輸入功能,并將教師資訊中的姓名,學院,職稱等,(如果工資資訊存在)更新給工資資訊,且在輸入完成后,顯示最新資訊,以便查驗,

3.3.2 delter() delsal()--洗掉教師資訊及薪資資訊

  1. void deleteter(char * id)
  2. {
  3. // through swap and cnt-- to complete the delete operation
  4. swapter(&ter[tercnt-1],&ter[searchterid(id)]);
  5. tercnt--;
  6. }
  7. void deletesal(char * id)
  8. {
  9. int i;
  10. for(i=0;i<salcnt;i++)
  11. {
  12. if(strcmp(sal[i].id,id) == 0)
  13. {
  14. swapsal(&sal[i],&sal[salcnt-1]);
  15. salcnt--;
  16. }
  17. FreshSalName(i); // to check bug
  18. }
  19. }

該洗掉方法為:交換當前元素和最后一位元素的全部資訊(通過自定swap實作,后續將進行介紹),并將總元素個數的統計變數減一,以此實作該洗掉操作,

3.3.3 自定義簡便SQL操作

已在3.0.0中介紹完畢,此處不再贅述,

3.4 Algorithm Functions 概述

該部分實作該程式的主要演算法功能,接下來將一一介紹各函式的實作方法,

3.4.1 showter()--可選mode的教師資訊串列列印函式

  1. int showter(int mode,char * cc)
  2. { // mode == 1: show all information
  3. // mode == 2: show NAME(tc)'s infromation
  4. // mode == 3: show ID(tc)'s information
  5. int re=-1;
  6. struct Teacher * tc;
  7. printf("\n---------------------------Basic Information---------------------\n");
  8. printf("|ID\t\t|NAME\t\t|COLLEGE\t|JOB\t\t|\n");
  9. printf("-----------------------------------------------------------------\n");
  10. for(tc=ter;tc<ter+tercnt;tc++)
  11. {
  12. if(mode == 1) printf("|%s\t|%-15s|%-15s|%-15s|\n",tc->id,tc->name,col_sec[tc->collegeid],job_sec[tc->jobid]);
  13. if(mode == 2 && (strcmp(tc->name,cc) == 0) ) printf("|%s\t|%-15s|%-15s|%-15s|\n",tc->id,tc->name,col_sec[tc->collegeid],job_sec[tc->jobid]);
  14. if(mode == 3 && (strcmp(tc->id,cc) == 0) )
  15. {
  16. re=tc-ter; // return his cntid
  17. printf("|%s\t|%-15s|%-15s|%-15s|\n",tc->id,tc->name,col_sec[tc->collegeid],job_sec[tc->jobid]);
  18. }
  19. }
  20. printf("-----------------------------------------------------------------\n\n");
  21. return re;
  22. }
  23. void showsal(int mode,char * cc,int mon)
  24. { // mode == 1: show all information
  25. // mode == 2: show NAME(tc)'s infromation
  26. // mode == 3: show ID(tc)'s information
  27. // if mon == 0 then cout every information
  28. // if mon == 1~12 then just cout the month's information
  29. struct Salary * sa;
  30. printf("\n-------------------------------------------------Salary Information------------------------------------------------------\n");
  31. printf("|Month\t|ID\t\t|NAME\t\t|Basic($)\t|Allowance($)\t|Subtract($)\t|Theory($)\t|True($)\t|\n");
  32. printf("-------------------------------------------------------------------------------------------------------------------------\n");
  33. for(sa=sal;sa<sal+salcnt;sa++)
  34. {
  35. if(mode == 1 && (mon==0?1:sa->month==mon)) printf("|%d\t|%-15s|%-15s|%-15.2f|%-15.2f|%-15.2f|%-15.2f|%-15.2f|\n",sa->month,sa->id,
  36. sa->name,sa->basicsal,sa->addsal,sa->subsal,sa->theosal,sa->truesal);
  37. if(mode == 2 && (strcmp(sa->name,cc) == 0) && (mon==0?1:(sa->month==mon))) printf("|%d\t|%-15s|%-15s|%-15.2f|%-15.2f|%-15.2f|%-15.2f|%-15.2f|\n",sa->month,sa->id,
  38. sa->name,sa->basicsal,sa->addsal,sa->subsal,sa->theosal,sa->truesal);
  39. if(mode == 3 && (strcmp(sa->id,cc) == 0) && (mon==0?1:(sa->month==mon))) printf("|%d\t|%-15s|%-15s|%-15.2f|%-15.2f|%-15.2f|%-15.2f|%-15.2f|\n",sa->month,sa->id,
  40. sa->name,sa->basicsal,sa->addsal,sa->subsal,sa->theosal,sa->truesal);
  41. }
  42. printf("-------------------------------------------------------------------------------------------------------------------------\n\n");
  43. }

當mode為1時,將展示所有教師的基本資訊或薪水資訊;當mode為2時,將展示姓名為所傳入引數的教師的基本資訊或薪水資訊;當mode為3時,將展示ID為所傳入引數的教師基本資訊或薪水資訊,

并且該函式利用了printf的格式化輸出功能,保證串列的整齊與美觀,

3.4.2 searchterid() searchsalid()--尋找所傳id對應的實際索引以便后續操作

  1. int searchterid(char * id)
  2. {
  3. int i;
  4. for(i=0; i < tercnt;i++)
  5. {
  6. if(strcmp(ter[i].id,id)== 0) return i;
  7. }
  8. return -1;
  9. }
  10. int searchsalid(char * id,int month)
  11. {
  12. int i;
  13. for(i=0;i<salcnt;i++)
  14. {
  15. if(strcmp(id,sal[i].id)==0 && sal[i].month == month) return i;
  16. }
  17. return -1;
  18. }

額外地,在考慮查詢月份需求的情況下,特假設month引數,以選擇特定的month進行輸出(給定 month和id時才能唯一的確定一條記錄),

3.4.3 swapter()swapsal()swapcol()swapjob()--交換函式

全部內容交換函式,通過臨時變數交換法實作,此處不做贅述,

3.4.4 sortter_id() sortsal_id()--排序函式

以id為序,對ter和sal的排序函式

  1. void sortter_id()
  2. { // make the ter list sorted by the id
  3. int i,j;
  4. for(i=0;i<tercnt;i++)
  5. for(j=tercnt-1;j>i;j--)
  6. if(strcmp(ter[j].id,ter[j-1].id)<0)
  7. swapter(&ter[j],&ter[j-1]);
  8. }
  9. void sortsal_id()
  10. { // make the sal list sorted by the 1:id 2:month
  11. int i,j;
  12. for(i=0;i<salcnt;i++)
  13. for(j=salcnt-1;j>i;j--)
  14. {
  15. if(strcmp(sal[j].id,sal[j-1].id)<0)
  16. swapsal(&sal[j],&sal[j-1]);
  17. if(strcmp(sal[j].id,sal[j-1].id) == 0)
  18. if(sal[j].month < sal[j-1].month)
  19. swapsal(&sal[j],&sal[j-1]);
  20. }
  21. }

由于禁止使用C++的algorithm庫及其sort函式,以及bool cmp() 排序規則,在此處我通過手寫的方式,實作了相應的功能,基于冒泡排序和前面的swap函式實作,

3.4.5 calcolavg_sort() caljobavg_sort()--實作統計分析排序功能的函式

  1. void calcolavg_sort(int mon)
  2. {
  3. int i,j;
  4. for(i=1;i<=Ncol;i++)
  5. {
  6. double thsum=0,trsum=0,cnt=0; // th->theory tr->true
  7. for(j=0;j<salcnt;j++)
  8. {
  9. if(sal[j].collegeid == i && sal[j].month == mon)
  10. {
  11. thsum += sal[j].theosal;
  12. trsum += sal[j].truesal;
  13. cnt++;
  14. }
  15. }
  16. col[i].collegeid = i;
  17. col[i].thavg= thsum?thsum/cnt:0;
  18. col[i].travg= trsum?trsum/cnt:0;
  19. }
  20. for(i=1;i<=Ncol;i++)
  21. for(j=Ncol;j>i;j--)
  22. {
  23. if(col[j].travg > col[j-1].travg)
  24. swapcol(&col[j],&col[j-1]);
  25. if(col[j].travg == col[j-1].travg)
  26. if(sal[j].collegeid < sal[j-1].collegeid)
  27. swapcol(&col[j],&col[j-1]);
  28. }
  29. }
  30. void caljobavg_sort(int mon)
  31. {
  32. int i,j;
  33. for(i=1;i<=Njob;i++)
  34. {
  35. double thsum=0,trsum=0,cnt=0; // th->theory tr->true
  36. for(j=0;j<salcnt;j++)
  37. {
  38. if(sal[j].jobid == i && sal[j].month == mon)
  39. {
  40. thsum += sal[j].theosal;
  41. trsum += sal[j].truesal;
  42. cnt++;
  43. }
  44. }
  45. job[i].jobid = i;
  46. job[i].thavg= thsum?thsum/cnt:0;
  47. job[i].travg= trsum?trsum/cnt:0;
  48. }
  49. for(i=1;i<=Njob;i++)
  50. for(j=Njob;j>i;j--)
  51. {
  52. if(job[j].thavg > job[j-1].thavg)
  53. swapjob(&job[j],&job[j-1]);
  54. if(job[j].travg == job[j-1].travg)
  55. if(sal[j].jobid < sal[j-1].jobid)
  56. swapjob(&job[j],&job[j-1]);
  57. }
  58. }

該段程式通過對所選職業或學院的相應工資資訊進行累加,并存盤在job和college兩個結構體中,最后對這兩個結構體進行排序實作以上功能,

3.4.6 FreshSalName()--同步sal與ter之間的資訊

由于涉及到對salary資訊與teacher資訊的同步更新,設定此函式

  1. void FreshSalName(int salind)
  2. {
  3. int i;
  4. for(i=0; i<tercnt;i++)
  5. {
  6. if(strcmp(ter[i].id,sal[salind].id) == 0)
  7. {
  8. strcpy(sal[salind].name,ter[i].name);
  9. sal[salind].collegeid=ter[i].collegeid;
  10. sal[salind].jobid=ter[i].jobid;
  11. break;
  12. }
  13. }
  14. }

通過比對id后,進行賦值,實作相應功能,

四、結果展示:

4.0開始界面

展示軟體資訊及版本資訊

進行321的倒計數后,進入程式的主界面

進入操作主選單

魯棒性測驗(只有輸入給定的運算元才可繼續)

4.1進入錄入資料并保存功能

4.1.1教師資訊錄入功能

(錄入學號姓名等,并以代號形式錄入學院,職稱資訊)

最終將該資訊以串列的形式列印出來

魯棒性測驗4.1.1.1(教師id重復)

魯棒性測驗4.1.1.2(教師id出現特殊字符,id過長,id過短)

魯棒性測驗4.1.1.3(學院、職稱出現特殊字符,過長,過短)

4.1.2錄入教師工資資訊

按照提示錄入相應資訊后,將會輸出該調工資資訊(人性化互動)

4.1.2.1 魯棒性測驗(輸入不存在的id)

4.1.2.2 魯棒性測驗(輸入不合法的月份資訊)

4.1.2.3魯棒性測驗(輸入不合法的錢數資訊)

4.1.3 保存到本地功能

已成功存盤到結構體和本地的dat檔案中,

4.2 進入修改資料并保存功能

4.2.1 根據工號修改某位教師的基本資訊和工資資訊

修改基礎資訊:

修改工資資訊:

4.2.1.1魯棒性測驗(當月份資訊不存在時)

4.2.1.2魯棒性測驗(當多次輸入錯誤月份資訊時)--跳出避免死回圈

其他魯棒性繼承于前序操作,此處不再重復演示,

4.2.2 根據姓名修改某位教師的基本資訊和工資資訊

Case1:該姓名不重復

Case2:該姓名存在重復情況 – 選擇所需要選擇的id輸出即可

4.2.2.1魯棒性測驗(所輸入的名字不存在) -- 提示重新輸入

4.2.3 洗掉某一工號的教師的所有資訊

將所有資訊列出后,要求輸入所要洗掉人的id

經過多次確認后方可洗掉,洗掉后輸出最新的全部資訊表格

4.3查詢顯示功能

4.3.1展示所有教師的基本資訊

4.3.2根據月份顯示所有教師當月工資資訊(以工號為序)

4.3.3根據工號查詢某位教師某一月份的基本資訊和工資資訊

4.3.4根據姓名查詢某位教師某一月份的基本資訊和工資資訊

Case1:無重復時

Case2:有重復時

4.3.4.1魯棒性測驗(姓名不存在)

4.4統計分析

4.4.1根據月份,統計不同學院教師的平均應發工資和平均實發工資

4.4.2根據月份,統計不同職稱教師的平均應發工資和平均實發工資

4.5從本地匯入資料(**創新點**)

可選從上次存盤資料中匯入,或從演示樣例資料中進行匯入

匯入成功后,將顯示所匯入的資訊

4.6保存并退出功能

經過多次確認后方可退出

退出感謝資訊

五、結束語:

以上為該程式的全部實作方法及演示,代碼已傳至個人GitHub上,該專案地址為:https://github.com/ShuoCHN/SalaryManageSystem,如有任何疑問或發現存在bug,請加私信與我進行討論,謝謝!

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/243886.html

標籤:其他

上一篇:定時器和中斷的關系,以及為什么應該盡量減少使用延時函式

下一篇:排序演算法第二談:快速排序

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more