【デザインの狙い】
1. 指導目的
このコースデザインは、「C言語プログラミング」コースを学習した後の学生を対象とした、総合的かつ総合的な研修であり、このコースデザインを通じて、C言語をプログラミングに活用する方法をより習得し、C言語の特徴やC言語の特徴について理解を深めることができます。 C言語の使用 プログラミングと開発プロセスを理解し、実践的なスキルを強化します。その主な目的は次のとおりです。
(1) 学生の C 言語プログラミングのアイデアをさらに育成し、基本的な言語要素と高級言語の制御構造についての理解を深めます。
(2) C 言語の重要で難しい内容についてトレーニングを提供し、一定の負荷のプログラミング タスクを自主的に完了し、適切なプログラミング スタイルを重視します。
(3) C言語のプログラミングスキルとコンピュータ上でプログラムをデバッグする方法を習得します。
(4) プログラミングにおける共通アルゴリズムを習得する。
2. 指導要件
(1) 与えられたトピックから任意の数のトピックを選択する必要があり、各学生は独立してコースデザインを完了する必要があり、相互に盗用することはできません。
(2) 設計が完了したら、完成した作品を弁護します。
(3) 詳細なコース設計レポートを作成する必要があります。
(4) プログラミングに関する質問については、対応するプログラムを提出し、注釈付きの正常に動作するソースプログラムを提供する必要があります。
【需要分析】
1. 質問
要件に応じて、システムには次の情報が含まれている必要があります。
各教師の情報は次のとおりです。
教員番号、氏名、性別、単元名、自宅住所、連絡先、
基本給、諸手当、生活手当、支払われる賃金、
電話代、水道代、電気代、家賃、所得税、医療費、積立金、控除総額、実際の賃金。
要件に従って、システムが実装する必要がある機能には次のものが含まれます。
1. 教師の情報処理:
(1) 講師情報を入力
(2) 教師情報を挿入(変更)します。
(3) 教師情報の削除
(4) 講師情報の閲覧
2. 教師データの処理:
(1) 教員の基本給、諸手当、生活手当、電話代、水道光熱費、家賃、所得税、医療費、積立金などの基本データを教員番号に応じて入力します。
(2) 教師の実際の賃金、支払われるべき賃金、および控除総額の計算。
1. 支払われる給与=基本給+諸手当+生活手当。
2. 控除総額 = 電話代 + 水道光熱費 + 家賃 + 所得税 + 医療費 + 積立金;
3. 実際の賃金 = 未払いの賃金 – 控除総額。
(3) 教師データの管理
ヒント: 新しいデータを入力し、変更された情報をファイルに書き込みます
(4) 教師データのクエリ
ヒント: 教師番号またはその他の情報を入力すると、すべてのデータ情報が読み取られて表示されます。
(5) 教師による総合的な情報発信
ヒント: 教師の情報を画面に出力します。
2. システム
C言語で実装されており、Windowsオペレーティングシステム上で実行できます。
3. 動作要件
教師データは制限なく入力できます。
インターフェースはフレンドリーで操作が簡単です。たとえば、教師の番号や名前に基づいて削除、変更、照会などの操作を実行できます。追加、削除、変更、照会の操作が完了すると、プログラムはリターンします。前のメニューへ。
フォールトトレラント性が高く、例えば、教師情報を追加する入力時に、教師番号、電話番号、性別などを認証し、入力ミスがあった場合にはエラーメッセージが表示され、プログラムは終了しません。異常な場合、プログラムは重複した名前の問題を処理します。
【全体デザイン】
1. システムプロセス設計
システム要件に応じて、図 1 に示すフローチャートを設計します。
図 1 - システム フロー
2.システムモジュールの設計
システムの機能設計によると、図 2 に示されています。
図 2 - システム機能図
メインインターフェースモジュール:システムメニューの表示を完了します
機能選択モジュール: ユーザーの選択に従って、対応する機能を完了します
教師情報の追加: ユーザーがインターフェースから教師情報を入力すると、教師データ情報がファイルに入力されます。
教師情報の削除: ユーザーの入力に基づいて、教師番号または名前に基づいて教師情報を削除するか、ホームページに戻るかプログラムを終了するかを決定します。
教師番号に基づく教師情報の削除:ユーザーがインターフェースから削除する教師番号を入力すると、システムは適格教師情報リンクリスト内の教師情報ノードを照会し、インターフェース上にノードを出力し、ユーザーに削除するかどうかを尋ねます。削除を確認します。ユーザーが確認すると、クエリされたリンク リスト ノードが削除され、リンク リストがファイルに保存されます。ユーザーがキャンセルすると、削除機能が終了し、前のメニューに戻ります。ユーザーが入力エラーを犯した場合、ループは引き続き、ユーザーが確認/キャンセルを選択できるようにします。
教師名に基づく教師情報の削除:ユーザーがインターフェースから削除する教師の名前を入力すると、システムは適格教師情報リンクリスト内の教師情報ノードを照会し、重複する名前を削除し、インターフェース上にノードを出力します。 、削除してもよいかどうかをユーザーに尋ねます。ユーザーが確認すると、クエリされたリンク リスト ノードが削除され、リンク リストがファイルに保存されます。ユーザーがキャンセルすると、削除機能が終了し、前のメニューに戻ります。ユーザーが入力エラーを犯した場合、ループは引き続き、ユーザーが確認/キャンセルを選択できるようにします。
教師情報の変更: ユーザーの入力に基づいて教師番号または名前に基づいて教師情報を変更するか、ホームページに戻るかプログラムを終了するかを判断する機能を完了します。
教師番号に基づいて教師情報を変更する: ユーザーがインターフェースから変更する教師番号を入力すると、システムは適格教師情報リンクリスト内の教師情報ノードを照会し、インターフェース上にノードを出力し、ユーザーに変更するかどうかを尋ねます。変更を確認します。ユーザーが確認した場合、ユーザーはインターフェイスから変更する教師情報を入力し、クエリされたリンク リスト ノードを変更し、リンク リストをファイルに保存します。ユーザーがキャンセルすると、変更機能は終了して前のメニューに戻ります。 ; ユーザーが入力した場合 エラーがある場合、ループはユーザーに確認/キャンセルを選択させ続けます。
教師名に基づいて教師情報を変更する: ユーザーがインターフェースから変更する教師名を入力すると、システムは重複名の影響を排除するために適格教師情報リンクリスト内の教師情報ノードを照会し、そのノードをインターフェースに出力します。 、そしてそれを変更するかどうかをユーザーに尋ねます。ユーザーが確認した場合、ユーザーはインターフェイスから変更する教師情報を入力し、クエリされたリンク リスト ノードを変更し、リンク リストをファイルに保存します。ユーザーがキャンセルすると、変更機能は終了して前のメニューに戻ります。 ; ユーザーが入力した場合 エラーがある場合、ループはユーザーに確認/キャンセルを選択させ続けます。
教師情報のクエリ: ユーザー入力に基づいて、教師番号または名前に基づいて教師情報をクエリするか、教師番号の順に教師情報を出力するか、給与の低い順に教師情報を出力するか、ホームページに戻るかを決定します。 、プログラムを終了します。
教師番号に基づいて教師情報を照会する: ユーザーがインターフェイスから照会する教師番号を入力し、適格な教師情報リンクリストをシステムに照会し、インターフェイスに表示する機能を完了します。
教師名に基づいて教師情報を照会する: ユーザーがインターフェースから照会する教師の名前を入力し、資格のある教師情報リンク・リストをシステムに照会し、それをインターフェースに表示する機能を完了します。
教師番号ごとに教師情報を表示: インターフェイスからのユーザー入力を行または列で表示し、すべての教師情報を教師番号ごとに低いものから高いものまで表示する機能を完了します。
給与別に教師情報を表示(低額 - >高額) : インターフェースからのユーザー入力を行または列に表示し、給与の低位から高位まですべての教師情報を表示する機能を完成します。
モジュールの概要を図 3 に示します。
図 3 - メニューに対応する各機能の一般的な実行を説明するフローチャート
【きめ細かなデザイン】
1. データ構造の設計
システム要件に応じて、システムに保存する必要があるデータには教師データ情報が含まれており、その構造は表 1 に示されています。
表 1 - 教師データ情報
データ項目名 |
データ項目システム表現 |
データの種類 |
データ長 |
述べる |
教師ID |
ID |
整数 |
|
|
名前 |
名前 |
弦 |
20 |
|
性別 |
セックス |
弦 |
5 |
|
会社名 |
職場 |
弦 |
100 |
|
自宅の住所 |
住所 |
弦 |
100 |
|
連絡先番号 |
電話番号 |
弦 |
20 |
|
基本給 |
給料 |
浮動小数点 |
|
|
手当 |
利点 |
浮動小数点 |
|
|
生活手当 |
生活手当 |
浮動小数点 |
|
|
未払いの賃金 |
支払うべき |
浮動小数点 |
|
|
電話料金 |
電話ビル |
浮動小数点 |
|
|
公共料金の請求書 |
水道代 |
浮動小数点 |
|
|
家賃 |
家賃を支払う |
浮動小数点 |
|
|
所得税 |
所得税 |
浮動小数点 |
|
|
衛生費 |
クリーンビル |
浮動小数点 |
|
|
準備基金 |
基金 |
浮動小数点 |
|
|
控除合計 |
合計控除額 |
浮動小数点 |
|
|
実際の賃金 |
リアルペイ |
浮動小数点 |
|
|
C言語で作成した構造は以下のとおりです。
typedef struct Teacher{
int id;//教师号
char name[20];//姓名
char sex[5];//性别
char workPlace[100];//单位名称
char address[100];//家庭住址
char tel[20];//联系电话
float salary;//基本工资
float benefit;//津贴
float livingAllowance;//生活补贴
float shouldPay;//应发工资
float telBill;//电话费
float warterBill;//水电费
float rentPay;//房租
float incomeTax;//所得税
float cleanBill;//卫生费
float fund;//公积金
float totalDeduct;//合计扣款
float realPay;//实发工资
struct Teacher *pnext;
} teacher;
2. インターフェース設計
メインインターフェイス:
システム要件に応じて、システムのメニューを表示するためのキャラクターインターフェイスを設計し、親しみやすさを反映するために、各メニューの前にメニュー項目に対応する番号を表示します。
ユーザーがメニュー項目の前に数字を入力すると、メイン メニューが消え、モジュールの対応するインターフェイスに入り、対応する操作を実行し、完了後にメイン インターフェイスに戻ります。
入力インターフェイスを図 4 に示します。
図 4 - 入力インターフェイス
教師情報を追加するためのインターフェイスを図 5 に示します。
図 5 - 教師情報の追加インターフェイス
教師情報を削除するためのインターフェイスを図 6 に示します。
図 6 - 教師情報の削除インターフェイス
教師番号に基づいて教師情報を削除するためのインターフェイスを図 7 に示します。
図 7 - 教師番号に基づいて教師情報を削除するインターフェイス
教師の名前に基づいて教師情報を削除するためのインターフェイスを図 8 と図 9 に示します。
図 8 - 教師名に基づいて教師情報を削除する (重複した名前がある) インターフェイス
図 9 - 教師名に基づいて教師情報を削除する (重複した名前はない) インターフェイス
教師情報を変更するためのインターフェイスを図 10 に示します。
図 10 - 教師情報の変更インターフェイス
教師番号に基づいて教師情報を変更するためのインターフェイスを図 11 に示します。
図 11 - 教師番号に基づいて教師情報インターフェイスを変更する
教師の名前に基づいて教師情報を変更するためのインターフェイスを図 12 と図 13 に示します。
図 12 - 教師名に基づいて教師情報インターフェイスを変更する (重複)
図 13 - 教師名に基づいて教師情報を変更する
教師情報をクエリするためのインターフェイスを図 14 に示します。
図 14 - 教師情報のクエリ インターフェイス
教師番号に基づいて教師情報をクエリするためのインターフェイスを図 15 に示します。
図 15 - 教師番号に基づいて教師情報をクエリするためのインターフェイス
教師の名前に基づいて教師情報をクエリするためのインターフェイスを図 16 に示します。
図 16 - 教師名に基づいて教師情報をクエリするためのインターフェイス
教師番号別に表示される教師情報インターフェースを図 17 に示します。
図 17 - 教師番号による教師情報インターフェイスの表示
教師情報を給与 (低額→高額) 別に表示するインターフェースを図 18 に示します。
図 18 - 給与別の教師情報インターフェイスの表示 (低額→高額)
3. モジュールの実装
(1)メインインターフェースの実装
printf() 関数を呼び出して、画面に表示する必要がある文字情報を印刷します。
(2) 機能選択モジュールの実装
キーボードからのメニュー選択入力を受け入れ、対応する機能を判断して呼び出し、対応する機能を完了します。機能選択を実装します。
対応機能:
void menu(){
system("cls");
char ch;
printf("***************教师工资管理系统***************\n");
printf("-------------------菜单列表-------------------\n");
printf("* 1:添加教师信息 *\n");
printf("* 2.删除教师信息 *\n");
printf("* 3:修改教师信息 *\n");
printf("* 4:查询教师信息 *\n");
printf("* 0.退出程序 *\n");
printf("**********************************************\n");
do{
printf("请选择:");
ch = getchar();
fflush(stdin);
switch(ch){
case '1':
addNode();
break;
case '2':
deleteNodeByIdOrName();
break;
case '3':
editNodeByIdOrName();
break;
case '4':
searchNodeByNameOrIdOrAll();
break;
case '0':
exit(0);
}
}while(ch!='0');
}
A. 教師情報モジュールを追加する
モジュールの説明:
ユーザはインターフェースから教師情報を入力し、新たなリンクリストノードに教師情報を格納し、教師データ情報を格納したリンクリストをファイルに格納する。
モジュールプロセス:
図 19 - addNode() 関数
対応機能:
void addNode(){
system("cls");
teacher *pnew;
char ch;
pnew=(teacher *)malloc(sizeof(teacher));
printf("请输入教师信息:\n");
printf("==========================================\n");
do{
printf("请输入教师号:");
scanf("%d",&pnew->id);
}while(check_number(pnew->id));
printf("请输入教师姓名:");
scanf("%s",&pnew->name);
do{
printf("请输入教师性别:");
scanf("%s",&pnew->sex);
}while(check_sex(pnew->sex));
printf("请输入教师单位名称:");
scanf("%s",&pnew->workPlace);
printf("请输入教师家庭住址:");
scanf("%s",&pnew->address);
do{
printf("请输入教师的电话号码:");
scanf("%s",&pnew->tel);
}while(check_tel(pnew->tel));
printf("==========================================\n");
printf("请输入教师基本工资:");
scanf("%f",&pnew->salary);
printf("请输入教师的津贴:");
scanf("%f",&pnew->benefit);
printf("请输入教师的生活补贴:");
scanf("%f",&pnew->livingAllowance);
pnew->shouldPay=pnew->salary+pnew->benefit+pnew->livingAllowance;
printf("========应发工资为:%.2f=============\n",pnew->shouldPay);
printf("请输入教师的电话费:");
scanf("%f",&pnew->telBill);
printf("请输入教师的水电费:");
scanf("%f",&pnew->waterBill);
printf("请输入教师的房租:");
scanf("%f",&pnew->rentPay);
printf("请输入教师的所得税:");
scanf("%f",&pnew->incomeTax);
printf("请输入教师的卫生费:");
scanf("%f",&pnew->cleanBill);
printf("请输入教师的公积金:");
scanf("%f",&pnew->fund);
pnew->totalDeduct=pnew->telBill+pnew->waterBill+pnew->rentPay+pnew->incomeTax+pnew->cleanBill+pnew->fund;
printf("========合计扣款为:%.2f=============\n",pnew->totalDeduct);
pnew->realPay=pnew->shouldPay-pnew->totalDeduct;
printf("==========实发工资为:%.2f=============\n",pnew->realPay);
printf("==========================================\n");
showNode(pnew);
printf("==========================================\n");
printf("确认录入该教师的信息吗(y/n):?\n");
do{
ch = getch();
if(ch == 'n'){
printf("取消成功!\n");
printf("\n-------按任意键回到主菜单--------");
getch();
getchar();
menu();
return;
}else if(ch =='y'){
if(pHead==NULL){
pHead=pnew;
pHead->pnext=NULL;
printf("录入成功!\n");
link_save();
printf("按任意键回到主菜单");
getch();
getchar();
menu();
return;
}
if(pHead->id>pnew->id){
teacher *pr=pHead;
pHead=pnew;
pHead->pnext=pr;
}else{
teacher *p;
teacher *bf;
p=pHead;
while(p->id<pnew->id){
bf=p;
p=p->pnext;
if(p==NULL){
bf->pnext=pnew;
pnew->pnext=NULL;
printf("录入成功!\n");
link_save();
printf("\n-------按任意键回到主菜单--------");
getch();
getchar();
menu();
return;
}
}
pnew->pnext=p;
bf->pnext=pnew;
}
printf("录入成功!\n");
link_save();
printf("\n-------按任意键回到主菜单--------");
getch();
getchar();
menu();
}else{
printf("确认录入该教师的信息吗(y/n):?\n");
}
} while(ch!='n'||ch!='y');
}
B. 教師情報モジュールの削除
モジュールの説明:
キーボードからのメニュー選択入力を受け入れ、対応する機能を判断して呼び出し、対応する機能を完了します。機能選択を実装します。
対応機能:
void deleteNode(teacher *node){
char ch;
printf("------------以下是要删除的教师信息------------\n");
showNode(node);
printf("----------------------------------------------\n");
printf("确定删除该信息吗(y/n):?\n");
do{
ch = getch();
if(ch == 'n'){
printf("取消成功!\n");
printf("--------按任意键回到菜单---------\n");
getch();
deleteNodeByIdOrName();
return;
}else if(ch =='y'){
if(node->id==pHead->id){
pHead=pHead->pnext;
free(node);
}else if(node->pnext==NULL){
teacher *k;
k=pHead;
while(k->pnext!=node){
k=k->pnext;
}
k->pnext=NULL;
}else{
teacher *d=pHead;
while(d->pnext!=node){
d=d->pnext;
}
d->pnext=node->pnext;
}
link_save();
printf("---------删除成功!---------------\n");
printf("--------按任意键回到菜单---------\n");
getch();
deleteNodeByIdOrName();
return;
}else{
printf("确定删除该信息吗(y/n):?\n");
}
} while(ch!='n'||ch!='y');
}
(a) 教師番号に基づいて教師情報を削除する
モジュールの説明:
ユーザーがインターフェースから削除する教師番号を入力すると、システムは適格教師情報リンクリスト内の教師情報ノードを照会し、そのノードをインターフェース上に出力し、ユーザーに削除を確認するかどうかを尋ねます。ユーザーが確認すると、クエリされたリンク リスト ノードが削除され、リンク リストがファイルに保存されます。ユーザーがキャンセルすると、削除機能が終了し、前のメニューに戻ります。ユーザーが入力エラーを犯した場合、ループは引き続き、ユーザーが確認/キャンセルを選択できるようにします。
モジュールプロセス:
図 20 - deleteNodeById() 関数
対応プログラム:
find=findLinkById();
if(find!=NULL){
deleteNode(find);
}else{
printf("系统中没有找到此教师\n");
printf("--------按任意键回到菜单---------\n");
getch();
deleteNodeByIdOrName();
}
(b) 教師名に基づいて教師情報を削除する
モジュールの説明:
ユーザーがインターフェースから削除する教師の名前を入力すると、システムは適格教師情報リンクリスト内の教師情報ノードを照会し、重複する名前要素を削除し、インターフェース上にノードを出力し、ユーザーに確認するかどうかを尋ねます。削除。ユーザーが確認すると、クエリされたリンク リスト ノードが削除され、リンク リストがファイルに保存されます。ユーザーがキャンセルすると、削除機能が終了し、前のメニューに戻ります。ユーザーが入力エラーを犯した場合、ループは引き続き、ユーザーが確認/キャンセルを選択できるようにします。
モジュールプロセス:
図 21 - deleteNodeByName() 関数
対応プログラム:
printf("请输入教师姓名:");
scanf("%s",&name);
nodes=findNodesByName(name,copyLink(pHead));
if(link_length(nodes)==1){
find=findLinkByName(nodes->name);
deleteNode(find);
break;
}else if(link_length(nodes)>1){
printf("有教师重名,删除失败!\n重名结果如下:\n");
printf("==========================================\n");
showLinkByRow(nodes);
printf("==========================================\n");
printf("\n提示:请根据教师号删除\n\n");
printf("--------按任意键回到菜单---------\n");
getch();
deleteNodeByIdOrName();
break;
break;
}else{
printf("系统中没有找到此教师\n");
printf("--------按任意键回到菜单---------\n");
getch();
deleteNodeByIdOrName();
break;
}
C. 教師情報モジュールの変更
モジュールの説明:
ユーザーの入力に基づいて、教師番号または名前に基づいて教師情報を変更するか、ホームページに戻るかプログラムを終了するかが決定されます。
対応機能:
void editNode(teacher *node){
char ch;
printf("------------以下是要修改的教师信息------------\n");
showNode(node);
printf("----------------------------------------------\n");
printf("确定修改该信息吗(y/n):?\n");
do{
ch = getch();
if(ch == 'n'){
printf("取消成功!\n");
printf("--------按任意键回到菜单---------\n");
getch();
editNodeByIdOrName();
return;
}else if(ch =='y'){
printf("请重新输入以下信息:\n");
printf("==========================================\n");
printf("请输入教师姓名:");
scanf("%s",&node->name);
printf("请输入教师性别:");
scanf("%s",&node->sex);
printf("请输入教师单位名称:");
scanf("%s",&node->workPlace);
printf("请输入教师家庭住址:");
scanf("%s",&node->address);
printf("请输入教师的电话号码:");
scanf("%s",&node->tel);
printf("==========================================\n");
printf("请输入教师基本工资:");
scanf("%f",&node->salary);
printf("请输入教师的津贴:");
scanf("%f",&node->benefit);
printf("请输入教师的生活补贴:");
scanf("%f",&node->livingAllowance);
node->shouldPay=node->salary+node->benefit+node->livingAllowance;
printf("=========应发工资为:%.2f==========\n",node->shouldPay);
printf("请输入教师的电话费:");
scanf("%f",&node->telBill);
printf("请输入教师的水电费:");
scanf("%f",&node->waterBill);
printf("请输入教师的房租:");
scanf("%f",&node->rentPay);
printf("请输入教师的所得税:");
scanf("%f",&node->incomeTax);
printf("请输入教师的卫生费:");
scanf("%f",&node->cleanBill);
printf("请输入教师的公积金:");
scanf("%f",&node->fund);
node->totalDeduct=node->telBill+node->waterBill+node->rentPay+node->incomeTax+node->cleanBill+node->fund;
printf("========合计扣款为:%.2f==========\n",node->totalDeduct);
node->realPay=node->shouldPay-node->totalDeduct;
printf("========实发工资为:%.2f===========\n",node->realPay);
printf("==========================================\n");
link_save();
printf("---------修改成功!---------------\n");
printf("--------按任意键回到菜单---------\n");
getch();
editNodeByIdOrName();
return;
}else{
printf("确定修改该信息吗(y/n):?\n");
}
} while(ch!='n'||ch!='y');
}
(a) 教師番号に応じて教師情報を変更する
モジュールの説明:
インターフェースから変更する教師番号を入力し、システム内の適格教師情報リンクリスト内の教師情報ノードを照会し、インターフェース上にノードを出力し、ユーザーに変更を確認するかどうかを尋ねます。ユーザーが確認した場合、ユーザーはインターフェイスから変更する教師情報を入力し、クエリされたリンク リスト ノードを変更し、リンク リストをファイルに保存します。ユーザーがキャンセルすると、変更機能は終了して前のメニューに戻ります。 ; ユーザーが入力した場合 エラーがある場合、ループは引き続きユーザーに確認/キャンセルを選択させます。
モジュールプロセス:
図 22 - editNodeById() 関数
対応プログラム:
find=findLinkById();
if(find!=NULL){
editNode(find);
}else{
printf("系统中没有找到此教师\n");
printf("--------按任意键回到菜单---------\n");
getch();
editNodeByIdOrName();
}
(b) 教師名に基づいて教師情報を変更する
モジュールの説明:
ユーザーがインターフェースから変更したい教師名を入力すると、システムは重複名の影響を排除するために適格教師情報リンクリスト内の教師情報ノードを照会し、そのノードがインターフェース上に出力され、ユーザーに尋ねられます。彼がそれを修正するかどうか。ユーザーが確認した場合、ユーザーはインターフェイスから変更する教師情報を入力し、クエリされたリンク リスト ノードを変更し、リンク リストをファイルに保存します。ユーザーがキャンセルすると、変更機能は終了して前のメニューに戻ります。 ; ユーザーが入力した場合 エラーがある場合、ループは引き続きユーザーに確認/キャンセルを選択させます。
モジュールプロセス:
図 23 - editNodeByName() 関数
対応プログラム:
printf("请输入教师姓名:");
scanf("%s",&name);
nodes=findNodesByName(name,copyLink(pHead));
if(link_length(nodes)==1){
find=findLinkByName(nodes->name);
editNode(find);
break;
}else if(link_length(nodes)>1){
printf("有教师重名,修改失败!\n重名结果如下:\n");
printf("==========================================\n");
showLinkByRow(nodes);
printf("==========================================\n");
printf("\n提示:请根据教师号修改\n\n");
printf("--------按任意键回到菜单---------\n");
getch();
editNodeByIdOrName();
break;
}else{
printf("系统中没有找到此教师\n");
printf("--------按任意键回到菜单---------\n");
getch();
editNodeByIdOrName();
break;
}
D. 教師情報のクエリモジュール
モジュールの説明:
ユーザの入力に基づいて、教師番号または名前に基づいて教師情報を照会するか、教師番号順に教師情報を出力するか、給与の低い順に教師情報を出力するか、または元に戻すかを決定します。ホームページを表示し、プログラムを終了します。
対応機能:
teacher * findLinkById(){
int id;
printf("请输入教师号:");
scanf("%d",&id);
if(pHead==NULL){
return NULL;
}else{
teacher *p=pHead;
while(id!=p->id){
p=p->pnext;
if(p==NULL){
return NULL;
}
}
return p;
}
}
teacher * findLinkByName(char *name){
if(pHead==NULL){
return NULL;
}else{
teacher *p=pHead;
while((strcmp(name,p->name))!=0){
p=p->pnext;
if(p==NULL){
return NULL;
}
}
return p;
}
}
teacher *findNodesByName(char *name,teacher *lista){
teacher* listb;
if (lista == NULL) return NULL;
while(lista!=NULL){
if(strcmp(name,lista->name)!=0){
lista = lista->pnext;
}else {
listb = (teacher*)malloc(sizeof(teacher));
listb->id=lista->id;
strcpy(listb->name,lista->name);
strcpy(listb->sex,lista->sex);
strcpy(listb->workPlace,lista->workPlace);
strcpy(listb->address,lista->address);
strcpy(listb->tel,lista->tel);
listb->salary=lista->salary;
listb->benefit=lista->benefit;
listb->livingAllowance=lista->livingAllowance;
listb->shouldPay=lista->shouldPay;
listb->telBill=lista->telBill;
listb->waterBill=lista->waterBill;
listb->rentPay=lista->rentPay;
listb->incomeTax=lista->incomeTax;
listb->cleanBill=lista->cleanBill;
listb->fund=lista->fund;
listb->totalDeduct=lista->totalDeduct;
listb->realPay=lista->realPay;
listb->pnext = findNodesByName(name,lista->pnext);
return listb;
}
}
}
(a) 教師番号に基づいて教師情報を問い合わせる
モジュールの説明:
ユーザーがインターフェースから照会したい教師番号を入力し、システム内の資格のある教師情報リンクリストを照会し、インターフェースに表示する機能を完了します。
モジュールプロセス:
図 24 – findLinkById() 関数
対応機能:
find=findLinkById();
if(find!=NULL){
printf("==========================================\n");
showNode(find);
printf("==========================================\n");
}else{
printf("系统中没有找到此教师\n");
}
printf("--------按任意键回到菜单---------\n");
getch();
searchNodeByNameOrIdOrAll();
break;
(b) 教師名に基づいて教師情報をクエリする
モジュールの説明:
ユーザーがインターフェースから問い合わせたい教師の名前を入力し、資格のある教師情報のリンクリストをシステムに問い合わせてインターフェースに表示する機能を完了します。
モジュールプロセス:
図 25 - findNodesByName() 関数
対応機能:
printf("请输入教师姓名:");
scanf("%s",&name);
find = findNodesByName(name,copyLink(pHead));
if(find!=NULL){
printf("==========================================\n");
if(link_length(find)==1){
showLink(find);
}else{
showLinkByRow(find);
}
printf("==========================================\n");
}else{
printf("系统中没有找到此教师\n");
}
printf("--------按任意键回到菜单---------\n");
getch();
searchNodeByNameOrIdOrAll();
break;
(c) 教師情報を教師番号順に出力する
モジュールの説明:
ユーザーはインターフェースから行または列で表示するか、すべての教師情報を教師番号ごとに低いものから高いものまで表示するかを選択できます。
モジュールプロセス:
図 26 - showLinkById() 関数
対応機能:
void showLinkByRowOrCol(teacher *head){
char ch;
printf("请选择按行输出(1)or按列输出(2):\n");
ch = getchar();
fflush(stdin);
switch(ch){
case '1':
showLinkByRow(head);
break;
case '2':
showLink(head);
break;
case '0':
exit(0);
}
}
void showLink(teacher *head){
teacher *p = head;
while (p !=NULL){
printf("教师号:%d\n姓名:%s\n性别:%s\n单位名称:%s\n家庭住址:%s\n联系电话:%s\n"
"基本工资:%.2f\n津贴: %.2f\n生活补贴:%.2f\n"
"应发工资:%.2f\n电话费: %.2f\n水电费: %.2f\n房租: %.2f\n所得税: %.2f\n"
"卫生费: %.2f\n公积金: %.2f\n合计扣款:%.2f\n实发工资:%.2f\n\n",
p->id,p->name,p->sex,p->workPlace,p->address,p->tel,p->salary,p->benefit,
p->livingAllowance,p->shouldPay,p->telBill,p->waterBill,
p->rentPay,p->incomeTax,p->cleanBill,p->fund,p->totalDeduct,p->realPay);
p = p->pnext;
}
}
(d)給与別に教師情報を出力(低額→高額)
モジュールの説明:
ユーザーはインターフェイスから行で表示するか列で表示するかを入力し、リンク リストをコピーし、再帰的並べ替えを使用してリンク リストの下位から上位まですべての教師情報を表示します。
モジュールプロセス:
図 27 - showLinkByRealPay() 関数
対応機能:
teacher* merge(teacher* list1,teacher* list2){
teacher* newList = (teacher*)malloc(sizeof(teacher));
teacher* nHead = newList;
teacher* nTail = newList;
newList->realPay = 0;
newList->pnext = NULL;
teacher* p = list1;
teacher* q =list2;
while(p!=NULL && q!=NULL){
if(p->realPay <= q->realPay){
nTail->pnext = p;
nTail = p;
p=p->pnext;
}else{
nTail->pnext = q;
nTail = q;
q=q->pnext;
}
}
if(p!=NULL) nTail->pnext = p;
if(q!=NULL) nTail->pnext = q;
return nHead->pnext;
}
teacher* sortList(teacher* head){
if(head==NULL) return head;
if(head->pnext==NULL) return head;
teacher* slow = head;
teacher* fast = head;
teacher* pre = NULL;
while(fast->pnext!=NULL && fast->pnext->pnext!=NULL){
pre=slow;
slow=slow->pnext;
fast=fast->pnext->pnext;
}
if(fast->pnext!=NULL){
pre=slow;
slow=slow->pnext;
}
teacher* mid = slow;
pre->pnext = NULL;
teacher* L1 =sortList(head);
teacher* L2 =sortList(mid);
return merge(L1,L2);
}
showLinkByRowOrCol(sortList(copyLink(pHead)));
【课设感想】
プログラムのハイライトは次のとおりです。
- 効率: 教師データの保存にはリンク リストが使用され、追加と削除は非常に効率的です。
- データ セキュリティ: すべてのリンク リスト データは txt ファイルに保存されます。プログラムをコンパイルするときに最初に行うことは、ファイルを読み取ることです。データの損失を防ぐために、保存する必要があるすべてのデータがファイルに配置されます。
- プログラムのセキュリティ: ユーザーの入力情報は入力処理中に検証され、データ形式のエラーによってプログラムが異常終了します。
- 新機能: マージ ソートを使用して、時間の複雑さを軽減しながら、教師の給与の低い順に教師の情報を出力します。バブル ソートを使用して、リンクされたリストに教師の情報が教師番号によって挿入されるたびに教師の情報を並べ替えます。
- 基本的な機能の実装を除き、バグは除外されます。
- リンクリストに重複した名前がある場合の削除、変更、検索の問題を解決しました。名前を削除・変更する場合、当初は名前を見つけて終了するプログラムでしたが、重複する名前情報を見つけて出力し、教師アカウントから削除・変更できるように修正しました。
- 情報入力時の正確性検証が解決されました。検証パラメータは次のとおりです: 教師番号 (重複なし)、教師の性別 (男性または女性)、電話番号 (正しい形式が必要)
欠点は次のとおりです。
- 関数の再利用率が低い。書かれたリンクリストの操作は基本的に教師クラス専用であり、他のプロジェクトに移すのは難しい。
- インターフェイスは十分に美しくありません。これは端末出力であるため、インターフェイスは完全に printf() に依存します。
- リンク リストはコピーされ、スペース リソースを占有します。プログラム設計当初は名前の重複の問題を考慮していなかったので、リンクリストの演算は全て教師番号順にソートされていました。ただし、給与順に並べ替える場合、リンクリストをコピーしないと順序が崩れてしまいますので、設計時に教員番号順に並べ替える機能を追加作成した場合は、この手順は不要です。
【Cプログラムのソースコード】
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FILENAME "teacherMsg.txt"
typedef struct Teacher{
int id;
char name[20];
char sex[5];
char workPlace[100];
char address[100];
char tel[20];
float salary;
float benefit;
float livingAllowance;
float shouldPay;
float telBill;
float waterBill;
float rentPay;
float incomeTax;
float cleanBill;
float fund;
float totalDeduct;
float realPay;
struct Teacher *pnext;
} teacher;
teacher * pHead = NULL;
FILE *file;
void menu();
int check_number(int id);
int check_tel(char *s);
int check_sex(char *s);
int link_length(teacher *head);
void read_file();
void link_save();
void showLink(teacher *head);
void showLinkByRow(teacher *head);
void showNode(teacher *node);
void showLinkByRowOrCol();
void addNode();
void deleteNodeByIdOrName();
void deleteNode(teacher *node);
void editNodeByIdOrName();
void editNode(teacher *node);
void searchNodeByNameOrIdOrAll();
teacher* findLinkById();
teacher* findLinkByName(char *name);
teacher *findNodesByName(char *name,teacher *head);
teacher* merge(teacher* list1,teacher* list2);
teacher* sortList(teacher* head);
teacher* copyLink(teacher* head);
int main(){
read_file();
menu();
}
void menu(){
system("cls");
char ch;
printf("***************教师工资管理系统***************\n");
printf("-------------------菜单列表-------------------\n");
printf("* 1:添加教师信息 *\n");
printf("* 2.删除教师信息 *\n");
printf("* 3:修改教师信息 *\n");
printf("* 4:查询教师信息 *\n");
printf("* 0.退出程序 *\n");
printf("**********************************************\n");
do{
printf("请选择:");
ch = getchar();
fflush(stdin);
switch(ch){
case '1':
addNode();
break;
case '2':
deleteNodeByIdOrName();
break;
case '3':
editNodeByIdOrName();
break;
case '4':
searchNodeByNameOrIdOrAll();
break;
case '0':
exit(0);
}
}while(ch!='0');
}
int check_number(int id){
teacher *p;
if(pHead==NULL){
return 0;
}else{
p=pHead;
while(p->id!=id){
p=p->pnext;
if(p==NULL)
return 0;
}
printf("教师号已存在!\n");
return 1;
}
}
int check_tel(char *s){
if(strlen(s) == 11&&s[0]=='1'&&((s[1]=='3') || (s[1]=='5') || (s[1]=='7') || (s[1]=='8'))){
return 0;
}else{
printf("手机号码不合法!\n");
return 1;
}
}
int check_sex(char *s){
if(strcmp(s,"男")==0||strcmp(s,"女")==0){
return 0;
}else{
printf("性别格式有误!\n");
return 1;
}
}
int link_length(teacher *head){
int length = 0;
teacher *n = head;
while(NULL != n){
++length;
n = n->pnext;
}
return length;
}
void read_file(){
file=fopen(FILENAME,"r+");
if(file==NULL){
file=fopen(FILENAME,"w");
if(file==NULL)
printf("\n\t文件创建失败!");
}else{
int k,len=0,c=0;
while((k=fgetc(file))!=EOF){
if(k=='\n'){
if(c!=1)
len++;
}
c++;
}
int id;
char name[20];
char sex[5];
char workPlace[100];
char address[100];
char tel[20];
float salary;
float benefit;
float livingAllowance;
float shouldPay;
float telBill;
float waterBill;
float rentPay;
float incomeTax;
float cleanBill;
float fund;
float totalDeduct;
float realPay;
teacher *p=(teacher *)malloc(sizeof(teacher));
rewind(file);
int i;
for(i=0;i<len;i++){
fscanf(file,"%d%s%s%s%s%s%f%f%f%f%f%f%f%f%f%f%f%f",
&id,name,sex,workPlace,address,tel,&salary,&benefit,&livingAllowance,
&shouldPay,&telBill,&waterBill,&rentPay,&incomeTax,&cleanBill,&fund,&totalDeduct,&realPay);
teacher *pn=(teacher *)malloc(sizeof(teacher));
pn->id=id;
strcpy(pn->name,name);
strcpy(pn->sex,sex);
strcpy(pn->workPlace,workPlace);
strcpy(pn->address,address);
strcpy(pn->tel,tel);
pn->salary=salary;
pn->benefit=benefit;
pn->livingAllowance=livingAllowance;
pn->shouldPay=shouldPay;
pn->telBill=telBill;
pn->waterBill=waterBill;
pn->rentPay=rentPay;
pn->incomeTax=incomeTax;
pn->cleanBill=cleanBill;
pn->fund=fund;
pn->totalDeduct=totalDeduct;
pn->realPay=realPay;
pn->pnext=NULL;
p->pnext=pn;
p=pn;
if(pHead==NULL){
pHead=p;
}
}
}
fclose(file);
}
void link_save(){
teacher *p = pHead;
if ((file = fopen(FILENAME, "w")) == NULL){
printf("文件创建失败!\n");
exit(1);
}
while(p!=NULL){
fprintf(file,"%d %s %s %s %s %s %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\n",
p->id,p->name,p->sex,p->workPlace,p->address,p->tel,p->salary,p->benefit,
p->livingAllowance,p->shouldPay,p->telBill,p->waterBill,p->rentPay,
p->incomeTax,p->cleanBill,p->fund,p->totalDeduct,p->realPay);
p=p->pnext;
}
fclose(file);
}
void showLink(teacher *head){
teacher *p = head;
while (p !=NULL){
printf("教师号:%d\n姓名:%s\n性别:%s\n单位名称:%s\n家庭住址:%s\n联系电话:%s\n"
"基本工资:%.2f\n津贴: %.2f\n生活补贴:%.2f\n"
"应发工资:%.2f\n电话费: %.2f\n水电费: %.2f\n房租: %.2f\n所得税: %.2f\n"
"卫生费: %.2f\n公积金: %.2f\n合计扣款:%.2f\n实发工资:%.2f\n\n",
p->id,p->name,p->sex,p->workPlace,p->address,p->tel,p->salary,p->benefit,
p->livingAllowance,p->shouldPay,p->telBill,p->waterBill,
p->rentPay,p->incomeTax,p->cleanBill,p->fund,p->totalDeduct,p->realPay);
p = p->pnext;
}
}
void showLinkByRow(teacher *head){
teacher *t = head;
teacher *p = head;
int i;
for(i=0;i<100;i++)printf("-");
printf("\n");
printf("教师号\t姓名\t性别\t单位\t家庭住址\t电话号\n");
while (t !=NULL){
printf("%d\t%-6s\t%2s\t%4s\t%4s\t\t%11s\t\n",
t->id,t->name,t->sex,t->workPlace,t->address,t->tel);
t = t->pnext;
}
for(i=0;i<100;i++)printf("-");
printf("\n");
printf("教师号\t姓名\t基本工资 津贴 生活补贴 电话费 水电费\t房租 所得税 卫生费 公积金 应付工资 合计扣款 实付工资\n");
while (p !=NULL){
printf("%-8d%-8s%-9.1f%-7.1f%-9.1f%-8.1f%-7.1f%-6.1f%-8.1f%-8.1f%-8.1f%-10.1f%-10.1f%-.1f\n",
p->id,p->name,p->salary,p->benefit,
p->livingAllowance,p->shouldPay,p->telBill,p->waterBill,
p->rentPay,p->incomeTax,p->cleanBill,p->fund,p->totalDeduct,p->realPay);
p = p->pnext;
}
for(i=0;i<100;i++)printf("-");
printf("\n");
}
void showNode(teacher *node){
printf("教师号:%d\n姓名:%s\n性别:%s\n单位名称:%s\n家庭住址:%s\n联系电话:%s\n"
"基本工资:%.2f\n津贴: %.2f\n生活补贴:%.2f\n"
"应发工资:%.2f\n电话费: %.2f\n水电费: %.2f\n房租: %.2f\n所得税: %.2f\n"
"卫生费: %.2f\n公积金: %.2f\n合计扣款:%.2f\n实发工资:%.2f\n\n",
node->id,node->name,node->sex,node->workPlace,node->address,node->tel,node->salary,node->benefit,
node->livingAllowance,node->shouldPay,node->telBill,node->waterBill,
node->rentPay,node->incomeTax,node->cleanBill,node->fund,node->totalDeduct,node->realPay);
}
void showLinkByRowOrCol(teacher *head){
char ch;
printf("请选择按行输出(1)or按列输出(2):\n");
ch = getchar();
fflush(stdin);
switch(ch){
case '1':
showLinkByRow(head);
break;
case '2':
showLink(head);
break;
case '0':
exit(0);
}
}
void addNode(){
system("cls");
teacher *pnew;
char ch;
pnew=(teacher *)malloc(sizeof(teacher));
printf("请输入教师信息:\n");
printf("==========================================\n");
do{
printf("请输入教师号:");
scanf("%d",&pnew->id);
}while(check_number(pnew->id));
printf("请输入教师姓名:");
scanf("%s",&pnew->name);
do{
printf("请输入教师性别:");
scanf("%s",&pnew->sex);
}while(check_sex(pnew->sex));
printf("请输入教师单位名称:");
scanf("%s",&pnew->workPlace);
printf("请输入教师家庭住址:");
scanf("%s",&pnew->address);
do{
printf("请输入教师的电话号码:");
scanf("%s",&pnew->tel);
}while(check_tel(pnew->tel));
printf("==========================================\n");
printf("请输入教师基本工资:");
scanf("%f",&pnew->salary);
printf("请输入教师的津贴:");
scanf("%f",&pnew->benefit);
printf("请输入教师的生活补贴:");
scanf("%f",&pnew->livingAllowance);
pnew->shouldPay=pnew->salary+pnew->benefit+pnew->livingAllowance;
printf("==========应发工资为:%.2f=============\n",pnew->shouldPay);
printf("请输入教师的电话费:");
scanf("%f",&pnew->telBill);
printf("请输入教师的水电费:");
scanf("%f",&pnew->waterBill);
printf("请输入教师的房租:");
scanf("%f",&pnew->rentPay);
printf("请输入教师的所得税:");
scanf("%f",&pnew->incomeTax);
printf("请输入教师的卫生费:");
scanf("%f",&pnew->cleanBill);
printf("请输入教师的公积金:");
scanf("%f",&pnew->fund);
pnew->totalDeduct=pnew->telBill+pnew->waterBill+pnew->rentPay+pnew->incomeTax+pnew->cleanBill+pnew->fund;
printf("==========合计扣款为:%.2f=============\n",pnew->totalDeduct);
pnew->realPay=pnew->shouldPay-pnew->totalDeduct;
printf("==========实发工资为:%.2f=============\n",pnew->realPay);
printf("==========================================\n");
showNode(pnew);
printf("==========================================\n");
printf("确认录入该教师的信息吗(y/n):?\n");
do{
ch = getch();
if(ch == 'n'){
printf("取消成功!\n");
printf("\n-------按任意键回到主菜单--------");
getch();
getchar();
menu();
return;
}else if(ch =='y'){
if(pHead==NULL){
pHead=pnew;
pHead->pnext=NULL;
printf("录入成功!\n");
link_save();
printf("按任意键回到主菜单");
getch();
getchar();
menu();
return;
}
if(pHead->id>pnew->id){
teacher *pr=pHead;
pHead=pnew;
pHead->pnext=pr;
}else{
teacher *p;
teacher *bf;
p=pHead;
while(p->id<pnew->id){
bf=p;
p=p->pnext;
if(p==NULL){
bf->pnext=pnew;
pnew->pnext=NULL;
printf("录入成功!\n");
link_save();
printf("\n-------按任意键回到主菜单--------");
getch();
getchar();
menu();
return;
}
}
pnew->pnext=p;
bf->pnext=pnew;
}
printf("录入成功!\n");
link_save();
printf("\n-------按任意键回到主菜单--------");
getch();
getchar();
menu();
}else{
printf("确认录入该教师的信息吗(y/n):?\n");
}
} while(ch!='n'||ch!='y');
}
void deleteNode(teacher *node){
char ch;
printf("------------以下是要删除的教师信息------------\n");
showNode(node);
printf("----------------------------------------------\n");
printf("确定删除该信息吗(y/n):?\n");
do{
ch = getch();
if(ch == 'n'){
printf("取消成功!\n");
printf("--------按任意键回到菜单---------\n");
getch();
deleteNodeByIdOrName();
return;
}else if(ch =='y'){
if(node->id==pHead->id){
pHead=pHead->pnext;
free(node);
}else if(node->pnext==NULL){
teacher *k;
k=pHead;
while(k->pnext!=node){
k=k->pnext;
}
k->pnext=NULL;
}else{
teacher *d=pHead;
while(d->pnext!=node){
d=d->pnext;
}
d->pnext=node->pnext;
}
link_save();
printf("---------删除成功!---------------\n");
printf("--------按任意键回到菜单---------\n");
getch();
deleteNodeByIdOrName();
return;
}else{
printf("确定删除该信息吗(y/n):?\n");
}
} while(ch!='n'||ch!='y');
}
void deleteNodeByIdOrName(){
system("cls");
char ch;
printf("***************教师工资管理系统***************\n");
printf("-----------------删除教师信息-----------------\n");
printf("* 1.根据教师号删除 *\n");
printf("* 2.根据教师姓名删除 *\n");
printf("* 3.回到主菜单 *\n");
printf("* 0.退出程序 *\n");
printf("**********************************************\n");
do{
printf("请选择:");
ch = getchar();
fflush(stdin);
switch(ch){
teacher *find;
teacher *nodes;
char name[20];
case '1':
find=findLinkById();
if(find!=NULL){
deleteNode(find);
}else{
printf("系统中没有找到此教师\n");
printf("--------按任意键回到菜单---------\n");
getch();
deleteNodeByIdOrName();
}
break;
case '2':
printf("请输入教师姓名:");
scanf("%s",&name);
nodes=findNodesByName(name,copyLink(pHead));
if(link_length(nodes)==1){
find=findLinkByName(nodes->name);
deleteNode(find);
break;
}else if(link_length(nodes)>1){
printf("有教师重名,删除失败!\n重名结果如下:\n");
printf("==========================================\n");
showLinkByRow(nodes);
printf("==========================================\n");
printf("\n提示:请根据教师号删除\n\n");
printf("--------按任意键回到菜单---------\n");
getch();
deleteNodeByIdOrName();
break;
break;
}else{
printf("系统中没有找到此教师\n");
printf("--------按任意键回到菜单---------\n");
getch();
deleteNodeByIdOrName();
break;
}
case '3':
menu();
break;
case '0':
exit(0);
break;
}
}while(ch!='0');
}
void editNode(teacher *node){
char ch;
printf("------------以下是要修改的教师信息------------\n");
showNode(node);
printf("----------------------------------------------\n");
printf("确定修改该信息吗(y/n):?\n");
do{
ch = getch();
if(ch == 'n'){
printf("取消成功!\n");
printf("--------按任意键回到菜单---------\n");
getch();
editNodeByIdOrName();
return;
}else if(ch =='y'){
printf("请重新输入以下信息:\n");
printf("==========================================\n");
printf("请输入教师姓名:");
scanf("%s",&node->name);
printf("请输入教师性别:");
scanf("%s",&node->sex);
printf("请输入教师单位名称:");
scanf("%s",&node->workPlace);
printf("请输入教师家庭住址:");
scanf("%s",&node->address);
printf("请输入教师的电话号码:");
scanf("%s",&node->tel);
printf("==========================================\n");
printf("请输入教师基本工资:");
scanf("%f",&node->salary);
printf("请输入教师的津贴:");
scanf("%f",&node->benefit);
printf("请输入教师的生活补贴:");
scanf("%f",&node->livingAllowance);
node->shouldPay=node->salary+node->benefit+node->livingAllowance;
printf("==========应发工资为:%.2f=============\n",node->shouldPay);
printf("请输入教师的电话费:");
scanf("%f",&node->telBill);
printf("请输入教师的水电费:");
scanf("%f",&node->waterBill);
printf("请输入教师的房租:");
scanf("%f",&node->rentPay);
printf("请输入教师的所得税:");
scanf("%f",&node->incomeTax);
printf("请输入教师的卫生费:");
scanf("%f",&node->cleanBill);
printf("请输入教师的公积金:");
scanf("%f",&node->fund);
node->totalDeduct=node->telBill+node->waterBill+node->rentPay+node->incomeTax+node->cleanBill+node->fund;
printf("==========合计扣款为:%.2f=============\n",node->totalDeduct);
node->realPay=node->shouldPay-node->totalDeduct;
printf("==========实发工资为:%.2f=============\n",node->realPay);
printf("==========================================\n");
link_save();
printf("---------修改成功!---------------\n");
printf("--------按任意键回到菜单---------\n");
getch();
editNodeByIdOrName();
return;
}else{
printf("确定修改该信息吗(y/n):?\n");
}
} while(ch!='n'||ch!='y');
}
void editNodeByIdOrName(){
system("cls");
char ch;
printf("***************教师工资管理系统***************\n");
printf("----------------修改教师信息-----------------\n");
printf("* 1.根据教师号修改 *\n");
printf("* 2.根据教师姓名修改 *\n");
printf("* 3.回到主菜单 *\n");
printf("* 0.退出程序 *\n");
printf("**********************************************\n");
do{
printf("请选择:");
ch = getchar();
fflush(stdin);
switch(ch){
teacher *find;
teacher *nodes;
char name[20];
case '1':
find=findLinkById();
if(find!=NULL){
editNode(find);
}else{
printf("系统中没有找到此教师\n");
printf("--------按任意键回到菜单---------\n");
getch();
editNodeByIdOrName();
}
break;
case '2':
printf("请输入教师姓名:");
scanf("%s",&name);
nodes=findNodesByName(name,copyLink(pHead));
if(link_length(nodes)==1){
find=findLinkByName(nodes->name);
editNode(find);
break;
}else if(link_length(nodes)>1){
printf("有教师重名,修改失败!\n重名结果如下:\n");
printf("==========================================\n");
showLinkByRow(nodes);
printf("==========================================\n");
printf("\n提示:请根据教师号修改\n\n");
printf("--------按任意键回到菜单---------\n");
getch();
editNodeByIdOrName();
break;
}else{
printf("系统中没有找到此教师\n");
printf("--------按任意键回到菜单---------\n");
getch();
editNodeByIdOrName();
break;
}
case '3':
menu();
break;
case '0':
exit(0);
break;
}
}while(ch!='0');
}
void searchNodeByNameOrIdOrAll(){
system("cls");
char ch;
printf("***************教师工资管理系统***************\n");
printf("-----------------查询教师信息-----------------\n");
printf("* 1.根据教师号查询 *\n");
printf("* 2.根据教师姓名查询 *\n");
printf("* 3.按教师号显示教师信息 *\n");
printf("* 4.按工资(低->高)显示教师信息 *\n");
printf("* 5.回到主菜单 *\n");
printf("* 0.退出程序 *\n");
printf("**********************************************\n");
do{
printf("请选择:");
ch = getchar();
fflush(stdin);
switch(ch){
teacher *find;
char name[20];
case '1':
find=findLinkById();
if(find!=NULL){
printf("==========================================\n");
showNode(find);
printf("==========================================\n");
}else{
printf("系统中没有找到此教师\n");
}
printf("--------按任意键回到菜单---------\n");
getch();
searchNodeByNameOrIdOrAll();
break;
case '2':
printf("请输入教师姓名:");
scanf("%s",&name);
find = findNodesByName(name,copyLink(pHead));
if(find!=NULL){
printf("==========================================\n");
if(link_length(find)==1){
showLink(find);
}else{
showLinkByRow(find);
}
printf("==========================================\n");
}else{
printf("系统中没有找到此教师\n");
}
printf("--------按任意键回到菜单---------\n");
getch();
searchNodeByNameOrIdOrAll();
break;
case '3':
showLinkByRowOrCol(pHead);
printf("--------按任意键回到菜单---------\n");
getch();
searchNodeByNameOrIdOrAll();
break;
case '4':
showLinkByRowOrCol(sortList(copyLink(pHead)));
printf("--------按任意键回到菜单---------\n");
getch();
searchNodeByNameOrIdOrAll();
break;
case '5':
menu();
break;
case '6':
exit(0);
break;
}
}while(ch!='0');
}
teacher * findLinkById(){
int id;
printf("请输入教师号:");
scanf("%d",&id);
if(pHead==NULL){
return NULL;
}else{
teacher *p=pHead;
while(id!=p->id){
p=p->pnext;
if(p==NULL){
return NULL;
}
}
return p;
}
}
teacher * findLinkByName(char *name){
if(pHead==NULL){
return NULL;
}else{
teacher *p=pHead;
while((strcmp(name,p->name))!=0){
p=p->pnext;
if(p==NULL){
return NULL;
}
}
return p;
}
}
teacher *findNodesByName(char *name,teacher *lista){
teacher* listb;
if (lista == NULL) return NULL;
while(lista!=NULL){
if(strcmp(name,lista->name)!=0){
lista = lista->pnext;
}else {
listb = (teacher*)malloc(sizeof(teacher));
listb->id=lista->id;
strcpy(listb->name,lista->name);
strcpy(listb->sex,lista->sex);
strcpy(listb->workPlace,lista->workPlace);
strcpy(listb->address,lista->address);
strcpy(listb->tel,lista->tel);
listb->salary=lista->salary;
listb->benefit=lista->benefit;
listb->livingAllowance=lista->livingAllowance;
listb->shouldPay=lista->shouldPay;
listb->telBill=lista->telBill;
listb->waterBill=lista->waterBill;
listb->rentPay=lista->rentPay;
listb->incomeTax=lista->incomeTax;
listb->cleanBill=lista->cleanBill;
listb->fund=lista->fund;
listb->totalDeduct=lista->totalDeduct;
listb->realPay=lista->realPay;
listb->pnext = findNodesByName(name,lista->pnext);
return listb;
}
}
}
teacher* merge(teacher* list1,teacher* list2){
teacher* newList = (teacher*)malloc(sizeof(teacher));
teacher* nHead = newList;
teacher* nTail = newList;
newList->realPay = 0;
newList->pnext = NULL;
teacher* p = list1;
teacher* q =list2;
while(p!=NULL && q!=NULL){
if(p->realPay <= q->realPay){
nTail->pnext = p;
nTail = p;
p=p->pnext;
}else{
nTail->pnext = q;
nTail = q;
q=q->pnext;
}
}
if(p!=NULL) nTail->pnext = p;
if(q!=NULL) nTail->pnext = q;
return nHead->pnext;
}
teacher* sortList(teacher* head){
if(head==NULL) return head;
if(head->pnext==NULL) return head;
teacher* slow = head;
teacher* fast = head;
teacher* pre = NULL;
while(fast->pnext!=NULL && fast->pnext->pnext!=NULL){
pre=slow;
slow=slow->pnext;
fast=fast->pnext->pnext;
}
if(fast->pnext!=NULL){
pre=slow;
slow=slow->pnext;
}
teacher* mid = slow;
pre->pnext = NULL;
teacher* L1 =sortList(head);
teacher* L2 =sortList(mid);
return merge(L1,L2);
}
teacher* copyLink(teacher* lista){
teacher* listb;
if (lista == NULL){
return NULL;
}else {
listb = (teacher*)malloc(sizeof(teacher));
listb->id=lista->id;
strcpy(listb->name,lista->name);
strcpy(listb->sex,lista->sex);
strcpy(listb->workPlace,lista->workPlace);
strcpy(listb->address,lista->address);
strcpy(listb->tel,lista->tel);
listb->salary=lista->salary;
listb->benefit=lista->benefit;
listb->livingAllowance=lista->livingAllowance;
listb->shouldPay=lista->shouldPay;
listb->telBill=lista->telBill;
listb->waterBill=lista->waterBill;
listb->rentPay=lista->rentPay;
listb->incomeTax=lista->incomeTax;
listb->cleanBill=lista->cleanBill;
listb->fund=lista->fund;
listb->totalDeduct=lista->totalDeduct;
listb->realPay=lista->realPay;
listb->pnext = copyLink(lista->pnext);
return listb;
}
}