/********************************************************** 作者: 劉家 時間:2015年12月24日02:44:48 編譯器:dev ***********************************************************/ # include <stdio.h> # include <stdlib.h> # include <string.h> # define MAX 50 # define MON 6 int count=0; //用於統計職工的總人數 struct Salary_Info { int Card_No; //工資卡號 char name[20]; //姓名 float Init_Salary; //應發工資 float Water_Rate; //水費 float Electric_Rate; //電費 float tax; //稅金 float Final_Salary; //實發工資 }; /*下面每個變量分別代表上面對應變量的變化 (用百分比表示)*/ struct Slary_Change{ float Init_Salary; float Water_Rate; float Electric_Rate; float tax; float Final_Salary; } ; /* 次結構體數組用於存放結構體變量中每個成員的平均值,因為是基於月份求的平均值,二我在存放 數據時 ,是把二維結構體數組的列下標作為月份來存的 而所得的平均值只有一個,所以定 義一個一維結構體數組存放 存放每一個沒個信息的平均值就可以了 */ struct Slary_Average{ float Init_Salary_Average; float Water_Rate_Average; float Electric_Rate_Average; float tax_Average; float Final_Salary_Average; }; struct Slary_Average Average[MAX]; //存放每個員工每個信息的平均值 struct Slary_Change Change[MAX][MON]; //存放每個員工每個信息的變化情況 struct Salary_Info Array[MAX][MON]; //存放每個員工的單一信息 void Load_Information(); //導入數據 void Keep_Information(); //保存數據 void Add_Information(); //添加數據 void Change_Information(); //修改信息 void Deleat_Information(); //刪除信息 int Find_Information(); //查找員工信息 void Output_Infromation(); //關於輸出信息的函數 void Output_One_Infromation(); //輸出單個信息 void Output_All_Infromation(); //輸出全部信息 void Output_Average_Information(int n); //輸出信息的平均值平均值 void Output_Change_Information(int n); //輸出信息的變化率 void Sort_Information(); //對員工的信息進行排序 void Echange_Information(int m ,int n); //將兩個員工的所有信息交換 void Calculate_Information(); // 計算已經存在的信息 void Inpu_Main_tValue(); //輸出主菜單 //主函數,將會從這裡選擇功能,進入相應的函數 int main() { int i; char ch; Load_Information(); do { Inpu_Main_tValue(); printf("請選擇功能:"); scanf("%d",&i); switch(i) { Inpu_Main_tValue(); case 1: Output_Infromation(); break; case 2: Add_Information(); break; case 3: Change_Information(); break; case 4: Deleat_Information(); break; case 5: Sort_Information(); break; case 6: Calculate_Information(); break; case 7: Keep_Information(); break; case 8: exit(0); break; } printf("是否返回主菜單?(Y/N)\n"); scanf(" %c",&ch); } while( ch=='y'||ch=='Y'); } void Load_Information() { int i,j; int n; FILE * fp; char ch [20]; putchar('\n'); printf("------------------------------------------------------------------------\n"); printf("| 請選擇信息導入方式 |\n"); printf("------------------------------------------------------------------------\n"); printf("| 1.自動導入本地文件 2.導入指定本地 |\n"); printf("------------------------------------------------------------------------\n"); putchar('\n'); printf("請選擇功能:"); scanf("%d",&n); if( n==1 ) { fp = fopen( "Information.txt","rb"); if( fp==NULL ) printf("沒有學生信息!\n"); else { //導入一個總人數 fread(&count,sizeof(int),1,fp ); //導入員工的基本信息 for ( i=0 ; i<count ; i++ ) { for (j=0 ; j<MON ;j++) { fread(&Array[i][j],sizeof(struct Salary_Info),1,fp); } } //導入一個信息的平均值 for ( i=0 ; i<count ; i++ ) { fread(&Average[i],sizeof(struct Slary_Average),1,fp); } //導入員工信息的變化率 for ( i=0 ; i<count ; i++ ) { for (j=0 ; j<MON ;j++) { fread(&Change[i][j],sizeof(struct Slary_Change),1,fp); } } } printf("導入信息成功!\n"); } else if( n==2 ) { printf("請輸入指定文件及其路徑:"); scanf("%s",&ch); fp = fopen( ch,"rb+"); fread(&count,sizeof(int),1,fp ); //導入一個總人數 fread(&count,sizeof(int),1,fp ); //導入員工的基本信息 for ( i=0 ; i<count ; i++ ) { for (j=0 ; j<MON ;j++) { fread(&Array[i][j],sizeof(struct Salary_Info),1,fp); } } //導入一個信息的平均值 for ( i=0 ; i<count ; i++ ) { fread(&Average[i],sizeof(struct Slary_Average),1,fp); } //導入員工信息的變化率 for ( i=0 ; i<count ; i++ ) { for (j=0 ; j<MON ;j++) { fread(&Change[i][j],sizeof(struct Slary_Change),1,fp); } } } else printf("輸入錯誤!\n"); fclose(fp); } void Keep_Information() { int i,j; int n; char ch_1[20]; // 用於存放路徑 char ch_2; //用於選擇循環 FILE * fp; fp = fopen( "Information.txt","wb+"); if (fp == NULL) return; putchar('\n'); printf("----------------------------------------------------------\n"); printf("| 請選擇信息導入方式 |\n"); printf("----------------------------------------------------------\n"); printf("| 1.自動保存至本地文件 2.保持至指定本地 |\n"); printf("----------------------------------------------------------\n"); putchar('\n'); printf("請選擇功能:"); scanf("%d",&n); if( n==1 ) { if( fp==NULL ) printf("保存失敗!\n"); //保存員工的個數 fwrite(&count,sizeof(int),1,fp ); //保存員工的基本信息 for ( i=0 ; i<count ; i++ ) { for (j=0 ; j<MON ;j++) { fwrite(&Array[i][j],sizeof(struct Salary_Info),1,fp); } } //保存一個信息的平均值 for ( i=0 ; i<count ; i++ ) { fwrite(&Average[i],sizeof(struct Slary_Average),1,fp); } //保存員工信息的變化率 for ( i=0 ; i<count ; i++ ) { for (j=0 ; j<MON ;j++) { fwrite(&Change[i][j],sizeof(struct Slary_Change),1,fp); } } } else if( n==2 ) { printf("請輸入指定文件及其路徑:"); scanf("%s",ch_1); fp = fopen( ch_1,"rb+"); //保存員工的個數 fwrite(&count,sizeof(int),1,fp ); //保存員工的基本信息 for ( i=0 ; i<count ; i++ ) { for (j=0 ; j<MON ;j++) { fwrite(&Array[i][j],sizeof(struct Salary_Info),1,fp); } } //保存一個信息的平均值 for ( i=0 ; i<count ; i++ ) { fwrite(&Average[i],sizeof(struct Slary_Average),1,fp); } //保存員工信息的變化率 for ( i=0 ; i<count ; i++ ) { for (j=0 ; j<MON ;j++) { fwrite(&Change[i][j],sizeof(struct Slary_Change),1,fp); } } } else printf("輸入錯誤!\n"); fclose(fp); } void Add_Information() { int n; int i,j; printf("請輸入要添加員工的人數:"); scanf("%d",&n); putchar('\n'); for ( i=count ; i<count+n ; i++ ) { printf("請輸入第%d個員工的信息:\n",i+1); printf("姓名: "); scanf("%s",Array[i][0].name); printf("工資卡號:"); scanf("%d",&Array[i][0].Card_No); putchar('\n'); for ( j=0 ; j<MON ; j++ ) { printf("請輸入第%d個員工第%d個月的信息。\n",i+1,j+1); printf("應發工資:"); scanf("%f",&Array[i][j].Init_Salary); printf("水費: "); scanf("%f",&Array[i][j].Water_Rate); printf("電費: "); scanf("%f",&Array[i][j].Electric_Rate); } } count = count + n; //更新總人數 /*將每個員工後面3個月的姓名與工資卡號復制*/ for ( i=0 ; i<count ; i++ ) { Array[i][2].Card_No = Array[i][1].Card_No = Array[i][0].Card_No; //Array[i][2].name = Array[i][1].name = Array[i][0].name; } } void Inpu_Main_tValue(){ printf("一共有%d個職工信息。\n",count); putchar('\n'); printf("------------------------------------------------------------------------\n"); printf("| 主菜單 |\n"); printf("------------------------------------------------------------------------\n"); printf("| 1.浏覽信息 2.添加信息 |\n"); printf("------------------------------------------------------------------------\n"); printf("| 3.修改信息 4.刪除信息 |\n"); printf("------------------------------------------------------------------------\n"); printf("| 5.排序信息 6.統計信息 |\n"); printf("------------------------------------------------------------------------\n"); printf("| 7.保存信息 8.退出系統(不保存) |\n"); printf("------------------------------------------------------------------------\n"); putchar('\n'); } /*總的選擇輸出函數,將會由其引導各種輸出*/ void Output_Infromation() { int i; char ch; printf("注意:使用此功能之前必須要先統計信息。\n"); printf("------------------------------------------------------------------------\n"); printf("| 1.浏覽所有員工的基本信息 2.浏覽單個員工的基本信息 |\n"); printf("------------------------------------------------------------------------\n"); printf("| 3.浏覽所有員工信息的平均值 4.浏覽單個員工信息的平均值 |\n"); printf("------------------------------------------------------------------------\n"); printf("| 5.浏覽所有員工信息的變化率 6.浏覽單個員工信息的變化率 |\n"); printf("------------------------------------------------------------------------\n"); printf("請選擇輸出方式:"); scanf("%d",&i); /* 此處設計的不合理,在輸出基本信息的時候我定義個2個函數分別輸出 單一和所有信息 而信息的平均值我就,先調用函數,然後在函數值判斷怎麼輸出 */ if( i==2 ) Output_One_Infromation(); else if( i==1 ) Output_All_Infromation(); else if( i==3||i==4) { Output_Average_Information(i); } else if ( i==5 || i==6 ) { Output_Change_Information(i); } else printf("選擇錯誤!"); return ; } int Find_Information() { int i; int Id_Number; //存放工資卡卡號 int n; char Name[20]; //存放姓名 printf("------------------------------------------------------------------------\n"); printf("| 1.按工資卡號查找 2.按姓名查找 |\n"); printf("------------------------------------------------------------------------\n"); printf("請選擇查找方式:"); scanf("%d",&n); if ( n==1) { printf("請輸入工資卡號:"); scanf("%d",&Id_Number); for ( i=0 ; i<count ; i++ ) { if( Array[i][0].Card_No==Id_Number) return i; } /*如果未查到,則返回-1,後面函數在接收返回值的時候也會進行檢查*/ if( i==count ) { printf("未查到該員工!\n"); return -1; } } else if(n==2) { printf("請輸入要查找的員工的姓名:"); scanf("%s",&Name); for ( i=0 ; i<count ; i++ ) { if( strcmp(Array[i][0].name,Name)==0) return i; } /*如果未查到,則返回-1,後面函數在接收返回值的時候也會進行檢查*/ if( i==count ) { printf("未查到該員工!\n"); return -1; } } else { printf("輸入錯誤!\n"); return -1; } return i; } void Output_One_Infromation() { int n; int i,j; printf("請先找到該員工。\n"); n = Find_Information(); if( n == -1 ) printf("未找到該員工"); printf("姓名:%s\n",Array[n][0].name); printf("工資卡:%d\n",Array[n][0].Card_No); putchar('\n'); printf("------------------------------------------------------------------------\n"); printf("| 月份 應發工資 水費 電費 稅金 實發工資 |\n"); printf("------------------------------------------------------------------------\n"); for ( i=0 ; i<MON ; i++ ) { printf(" %4.1d %4.1f %4.1f %4.1f %4.1f %4.1f ", i+1,Array[n][i].Init_Salary,Array[n][i].Water_Rate,Array[n][i].Electric_Rate ,Array[n][i].tax,Array[n][i].Final_Salary); } putchar('\n'); } //輸出所有一個的基本信息 void Output_All_Infromation() { int i,j; putchar('\n'); printf("------------------------------------------------------------------------\n"); printf("| 月份 應發工資 水費 電費 稅金 實發工資 |\n"); printf("------------------------------------------------------------------------\n"); for ( i=0 ; i<count ; i++ ) { printf("第%d個人的信息:",i+1); printf("姓名:%s",Array[i][0].name); printf(" 工資卡號:%d\n",Array[i][0].Card_No); putchar('\n'); for (j=0 ; j<MON ; j++ ) { printf(" %4.1d %4.1f %4.1f %4.1f %4.1f %4.1f ", j+1,Array[i][j].Init_Salary,Array[i][j].Water_Rate,Array[i][j].Electric_Rate ,Array[i][j].tax,Array[i][j].Final_Salary); putchar('\n'); } putchar('\n'); } } void Output_Average_Information(int i) { int j ; printf("------------------------------------------------------------------------\n"); printf("| 員工信息平均值統計 |\n"); printf("------------------------------------------------------------------------\n"); printf("| 姓名 工資卡號 應發工資 水費 電費 稅金 實發工資 |\n"); printf("------------------------------------------------------------------------\n"); if( i==3 ) { for ( i=0 ; i<count ; i++) { printf(" %s %4d %4.1f %4.1f %4.1f %4.1f %4.1f ",Array[i][0].name, Array[i][0].Card_No,Average[i].Init_Salary_Average,Average[i].Water_Rate_Average, Average[i].Electric_Rate_Average,Average[i].tax_Average,Average[i].Final_Salary_Average); putchar('\n'); } } if( i==4 ) { int n; printf("請先找出要浏覽員工:"); n = Find_Information(); if( n==-1) printf("未找到該員工!\n"); else { printf(" %s %4d %4.1f %4.1f %4.1f %4.1f %4.1f %4.1f",Array[i][0].name, Array[i][0].Card_No,Average[i].Init_Salary_Average,Average[i].Water_Rate_Average, Average[i].Electric_Rate_Average,Average[i].tax_Average,Average[i].Final_Salary_Average); putchar('\n'); } } } //輸出信息的變化率 void Output_Change_Information(int n) { int i,j; if( n==5) { printf("------------------------------------------------------------------------\n"); printf("| 月份 應發工資 水費 電費 稅金 實發工資 |\n"); printf("------------------------------------------------------------------------\n"); for ( i=0 ; i<count ; i++ ) { printf("變化率:"); printf("姓名:%s 工資卡號: %d\n",Array[i][0].name,Array[i][0].Card_No); putchar('\n'); for ( j=1 ; j<MON ; j++ ) { printf(" %d \t %2.1f% \t %2.1f% \t %2.1f% \t %2.1f% \t %2.1f% ", j+1,Change[i][j].Init_Salary,Change[i][j].Water_Rate,Change[i][j].Electric_Rate ,Change[i][j].tax,Change[i][j].Final_Salary); putchar('\n'); } } } } void Sort_Information() { int i,j; int n; printf(" 注意:使用此功能錢,必須先使用 6.統計信息!\n"); printf("------------------------------------------------------------------------\n"); printf("| 1.按平均工資排序 2.按平均工資增長率排序 |\n"); printf("------------------------------------------------------------------------\n"); printf("請選擇排序方式:"); scanf("%d",&n); if( n==1 ) { for ( i=0 ; i<count ; i++ ) { for ( j=i+1 ; j<count ; j++ ) { if( Average[i].Final_Salary_Average>Average[j].Final_Salary_Average); /* 次出設計的不怎麼好,因為每次交換來個員工的基本信息之後都會對所有信 息進行一次計算,應該再寫一個對2個員工的信息進行計算的函數,但是 我不想寫了。 */ Echange_Information(i,j); } } } else if( n==2 ) { } else { printf("輸入錯誤!\n"); return; } printf("排序成功!\n"); } /* 交換2個員工的說有信息 */ void Echange_Information(int m ,int n) { int i; struct Salary_Info temp_1; /* 此處已經確定2個員工的序號(結構體數組的行下標) 只需要交換該員工所對應的每個結構體類型的,每個月的 數據即可 */ for ( i=0 ; i<MON ; i++ ) { /*交換每個學生原始信息*/ temp_1 = Array[m][i]; Array[m][i] =Array[n][i]; Array[n][i] = temp_1; /* 為了避免將每個員工每個月的每種信息進行交換 我選擇值叫換基本的信息,比如平均值,變化率 什麼的,我選擇在交換基本信息之後重新計算 */ } } void Change_Information() { int i,j; int n; int flag; printf("請先找出要修改的信息!\n"); n = Find_Information(); if( n==-1 ) { printf("未找到該員工!\n"); return ; } else { char ch; printf("姓名:%s\n",Array[n][0].name); printf("工資卡:%d\n",Array[n][0].Card_No); putchar('\n'); printf("------------------------------------------------------------------------\n"); printf("| 月份 應發工資 水費 電費 稅金 實發工資 |\n"); printf("------------------------------------------------------------------------\n"); for ( i=0 ; i<MON ; i++ ) { printf(" %4.1d %4.1f %4.1f %4.1f %4.1f %4.1f ", i+1,Array[i][0].Init_Salary,Array[i][0].Water_Rate,Array[i][0].Electric_Rate ,Array[i][0].tax,Array[i][0].Final_Salary); putchar('\n'); } printf("是否修改以上信息?(Y/N)\n"); scanf(" %c",&ch); /**正式修改信息*/ if(ch=='Y'||ch=='y') { printf("請輸入該員工的新信息。\n"); printf("姓名: "); scanf("%s",Array[n][0].name); printf("工資卡號:"); scanf("%d",&Array[n][0].Card_No); putchar('\n'); for ( j=0 ; j<MON ; j++ ) { printf("請輸入該員工員工第%d個月的信息。\n",j+1); printf("應發工資:"); scanf("%f",&Array[n][j].Init_Salary); printf("水費: "); scanf("%f",&Array[n][j].Water_Rate); printf("電費: "); scanf("%f",&Array[n][j].Electric_Rate); } } else { return; } } } void Deleat_Information() { int n,i,j; char ch; printf("請先找出你要刪除的信息!\n"); n = Find_Information(); if( n == -1 ) { printf("未找到該員工!\n"); return ; } putchar('\n'); printf("姓名:%s\n",Array[n][0].name); printf("工資卡:%d\n",Array[n][0].Card_No); putchar('\n'); printf("------------------------------------------------------------------------\n"); printf("| 月份 應發工資 水費 電費 稅金 實發工資 |\n"); printf("------------------------------------------------------------------------\n"); for ( i=0 ; i<MON ; i++ ) { printf(" %4.1d %4.1f %4.1f %4.1f %4.1f %4.1f ", i+1,Array[n][i].Init_Salary,Array[n][i].Water_Rate,Array[n][i].Electric_Rate ,Array[n][i].tax,Array[n][i].Final_Salary); putchar('\n'); } putchar('\n'); printf("是否刪除以上信息?(Y/N)\n"); scanf(" %c",&ch); if ( ch=='Y'||ch == 'y') { for( i=n ; i<count-1 ; i++ ) { for ( j=0 ; j<MON ; j++ ) { Array[i][j] = Array[i+1][j]; } } count--; printf("刪除成功!\n"); } else { return ; } } /*計算各個員工的信息的平均值,變換*/ void Calculate_Information() { int i,j; char ch; /* 計算每個員工每個月應該繳納的稅金 */ for ( i=0 ; i<count ; i++ ) { for( j=0 ; j<MON ; j++ ) { if( Array[i][j].Init_Salary<=800 ) Array[i][j].tax=0; else if( Array[i][j].Init_Salary>800&& Array[i][j].Init_Salary<1400) Array[i][j].tax = ( Array[i][j].Init_Salary-800)*float(0.05); else if ( Array[i][j].Init_Salary>1400 ) Array[i][j].tax = ( Array[i][j].Init_Salary-1400)*float(0.1); } } /*計算每個員工每個月最後得到的工資*/ for ( i=0 ; i<count ; i++ ) { for ( j=0 ; j<MON ; j++ ) { Array[i][j].Final_Salary = Array[i][j].Init_Salary - Array[i][j].Electric_Rate- Array[i][j].Water_Rate - Array[i][j].tax; } } /*計算每個員工每個信息的平均值*/ /*分別定義出用於存放沒個信息總數值的變量*/ float Average_Sum_Init_Salary; float Average_Sum_Water_Rate; float Average_Sum_Electric_Rate; float Average_Sum_tax; float Average_Sum_Final_Salary; for ( i=0 ; i<count ; i++ ) { for( j=0 ; j<MON ; j++ ) { Average_Sum_Init_Salary += Array[i][j].Init_Salary; Average_Sum_Water_Rate+= Array[i][j].Water_Rate; Average_Sum_Electric_Rate += Array[i][j].Electric_Rate; Average_Sum_tax+= Array[i][j].tax; Average_Sum_Final_Salary += Array[i][j].Final_Salary; } /*每個員工的每個信息的平均值*/ Average[i].Init_Salary_Average = Average_Sum_Init_Salary / MON; Average[i].Water_Rate_Average = Average_Sum_Water_Rate / MON; Average[i].Electric_Rate_Average = Average_Sum_Electric_Rate / MON; Average[i].tax_Average = Average_Sum_tax / MON; Average[i].Final_Salary_Average = Average_Sum_Final_Salary /MON; /*在計算玩平均值後要講總和這個變量的值初始化為0,不然後面會出錯*/ Average_Sum_Init_Salary=0; Average_Sum_Water_Rate=0; Average_Sum_Electric_Rate=0; Average_Sum_tax=0; Average_Sum_Final_Salary=0; } /*計算每個員工每個月於前一個月的變化率*/ for( i=0 ; i<count ; i++ ) { /*分別計算每個員工種信息每個月的變化率*/ for ( j=1 ; j<MON ; j++ ) { Change[i][j].Init_Salary = (Array[i][j].Init_Salary - Array[i][j-1].Init_Salary) / Array[i][j].Init_Salary; Change[i][j].Electric_Rate = (Array[i][j].Electric_Rate - Array[i][j-1].Electric_Rate) / Array[i][j].Electric_Rate; Change[i][j].Water_Rate = (Array[i][j].Water_Rate - Array[i][j-1].Water_Rate) / Array[i][j].Water_Rate; Change[i][j].tax = (Array[i][j].tax - Array[i][j-1].tax) / Array[i][j].tax; Change[i][j].Final_Salary = (Array[i][j].Final_Salary - Array[i][j-1].Init_Salary) / Array[i][j].Final_Salary; } } printf("計算結束!\n"); }