【C语言】学生/员工信息管理系统

一、系统特点

亮点1:双语交互界面系统可适性好。

教师管理系统:

身份选择、密钥对证、系统语言选择:

 中文交互界面:

 开辟空间:

添加并查找学生信息:

修改并查找学生信息:

 

删除并查找学生信息:

 

增扩空间&写入:

格式化:

亮点2:最外层设置身份认证,若为教师则进行密钥认证(strcmp)

若为学生则进入学生管理系统。

亮点3:教师能实现增删改查学生只能查看自己的信息,不能修改(只读)。

亮点4:在学生人数过多的情况下,师能够增添哈希表的单元格数量

亮点5:使用文件IO,每个学生都有一个其姓名对应的.txt文件保存个人信息。

 

 

 

 

 

 

这样教师在录入完学生的信息后,会自动保存至对应文件,教师退出系统后,学生再进入系统,依旧可以访问到数据。

人性化设计:

亮点6:一个面向用户的管理系统,里面的操作用黑匣子封装,用户无需了解对应的步骤并具体的去操作,简单来说就是抬高C语言的维度,把功能再封装,已达到减少用户操作数的目的。

就比如:

①我在教师模式下,选择添加学生信息,我不需要用户去“输入添加的结构体类型数据——索引并插入哈 希表——打开文件——信息写入文件”这样操作。

我直接封装一个“添加学生信息”,里面有上面的所有功能。

②或是我在学生模式下,查看学生的信息,我不需要用户“创建哈希表——打开文件——读取文件——将 信息写入当前哈希表中——查找”这样操作。

同理,我封装了“查找学生信息”这一个模块,它里面有上面的所有功能。

③退出系统自动进行关闭文件等操作,学生模式下还会自动释放空间无需按多次按钮,多步变一步。

二、源代码:

1.主函数(main.c)

  1 #include "../include/main.h"                                                                                                                                   
  2 
  3 int main()
  4 {
  5     ht * ht1_head = NULL;   //哈希表的表头指针
  6     link_node ** ht1 = NULL;//指向哈希表的指针
  7     int n = 0;              //哈希表的单元格数
  8     int m = 0;              //哈希表的增扩单元格数
  9     link_node * ln_new = NULL;//指向链表节点的指针,在子函数里申请空间
 10 
 11     data_type stu1;     //存放学生数据的结构体,add子函数要用
 12     memset(&stu1,0,sizeof(stu1));//初始化一下
 13     char ID[20] = {'\0'};   //存放一个学生的ID,search子函数要用
 14     link_node * ln0 = NULL;//定义一个链表节点类型的指针,在search后显示节点内容要用
 15 
 16 
 17     int a = 0;          //用户身份选项
 18     char key[6] = "114514";//教师的密钥
 19     char s[6];             //输入密钥缓冲区
 20     memset(s,0,sizeof(s)); //缓冲区的初始化
 21     int op_tch_l = 0;   //教师菜单语言选项
 22     int op_tch =0;      //教师菜单选项
 23         int op_stu_l = 0;   //学生菜单语言选项
 24     int op_stu = 0;     //学生菜单选项
 25     int file = -1;      //文件描述符,注意这里的初始化,不能跟正常打开的描述符搞混
 26     int g=0,j=0;        //读写指示符,接受read,write的返回值
 27     char sss[20];       //保存学生信息的文件的文件名
        memset(sss,0,sizeof(sss));
 28     printf("Welcome to the XXX university's management system of students information!\n");
 29     putchar('\n');
 30     printf("Teacher / Student?\n");
 31     printf("1---------Teacher\n");      //不使用0,因为a初始化的值是0
 32     printf("2---------Student\n"); 
 33     scanf("%d",&a);
 34 
 35     if(a == 1)              //开启用户为教师的执行步骤!!!
 36     {
 37         int i = 0;
 38         for(;i<5;i++)       //我设定5次的输入密码机会
 39         {
 40             printf("Please input the key:\n");
 41             scanf("%s",s);
 42             if ( strncmp(s,key,6) !=0 )
 43             {
 44                 printf("Error key!!!\n");
 45                 printf("Access denied!!!\n");
 46                 continue;
 47             }
 48             else
 49             {
 50                 printf("Correct key!!!\n");
 51                 printf("Access permitted!\n");
 52                 putchar('\n');
 53                 printf("请选择菜单语言\n");
 54                 printf("Chose the menu language.\n");
 55                 printf("1---------中文\n");
 56                 printf("2---------English\n");
 57                 putchar('\n');
 58                 scanf("%d",&op_tch_l);                                                                                                                         
 59                 if(op_tch_l==1)             //用户选择中文菜单
 60                 {
 61 
 62                     //这里开始的就是咱们的老步骤了
 63                     while(1)
 64                     {
65                         menu_tch1();        //!!!中英文菜单只有菜单和提示语不同
 66                         printf("请输入操作数:\n");          //其余操作肯定都是一样的
 67                         scanf("%d",&op_tch);
 68                         switch(op_tch)
 69                         {
 70                         case 0:
 71                             if(file!=-1)    //文件如果开着就给它关了
 72                             {
 73                                 close(file);
 74                             }
 75                             printf("已退出!\n");
 76                             printf("祝您生活愉快!\n");
 77                             return 0;
 78                         case 1:
 79                             printf("开辟空间:\n");
 80                             printf("您想开辟多少单元格?\n");
 81                             scanf("%d",&n);
 82                             infomalloc1(&ht1,&ht1_head,n);
 83                             break;
 84                         case 2://添加完学生信息顺便写入到文件里
 85                             printf("添加学生信息:\n");
 86                             printf("请输入想要添加的学生信息:\n");
 87                             printf("姓名:\n");
 88                             scanf("%s",stu1.Name);
 89                             printf("性别:\n");
 90                             scanf("%s",stu1.Gender);
 91                             printf("学号:\n");                                                                                                                
 92                             scanf("%s",stu1.ID);
 93                             printf("成绩:\n");
 94                             scanf("%s",stu1.Grade);
 95                             printf("输入完毕!\n");
 96                             add1(ht1_head,&ln_new,stu1);
                                sprintf(sss,"%s.txt",stu1.Name);
97                             //打开文件
 98                             file = open(sss,O_RDWR | O_CREAT | O_TRUNC,0664);
 99                             //写入即可
100                             j = write(file,&stu1,sizeof(data_type));
101                             if(j==-1)
102                             {
103                                 printf("写入文件失败!\n");
104                                 return -1;
105                             }
106                             printf("写入文件成功!\n");
107                             break;
108                         case 3:
109                             printf("修改学生信息:\n");
110                             printf("请输入修改后的学生信息\n");
111                             printf("姓名:\n");
112                             scanf("%s",stu1.Name);
113                             printf("性别:\n");
114                             scanf("%s",stu1.Gender);
115                             printf("学号:\n");
116                             scanf("%s",stu1.ID);
117                             printf("成绩:\n");
118                             scanf("%s",stu1.Grade);
119                             printf("输入完毕\n");
120                             modify1(ht1_head,stu1);
121                             break;
122                         case 4:
123                             printf("查找学生信息:\n");                                                                                                        
124                             printf("请输入想要查找的学生学号\n");
125                             scanf("%s",ID);
126                             ln0 = search1(ht1_head,ID);
127                             if(ln0 != NULL)
128                             {
129                                 printf("该学生的信息如下:\n");
130                                 printf("姓名:%s\n",ln0->stu_data.Name);
131                                 printf("性别%s\n",ln0->stu_data.Gender);
132                                 printf("学号:%s\n",ln0->stu_data.ID);
133                                 printf("成绩:%s\n",ln0->stu_data.Grade);
134                             }
135                             break;
136                         case 5:
137                             printf("删除学生信息:\n");
138                             printf("请输入想要删除的学生学号:\n");
139                             scanf("%s",ID);
140                             delete1(&ht1_head,ID);//子函数里实现查找并释放空间
141                             break;
142                         case 6:
143                             printf("增扩空间:\n");
144                             printf("请输入想要扩展的行数:\n");
145                             scanf("%d",&m);
146                             expand1(ht1,&ht1_head,m,n);
147                             break;
148                         case 999:
149                             printf("格式化中...\n");
150                             formatting1(&ht1_head,&ht1);
151                             break;
152                         default:
153                             printf("请检查操作数!\n");
154 
155                         }                                                                                                                                      
156                     }//while
157 
158                 }
159 
160                 else if(op_tch_l==2)            //用户选择英文菜单
162                     while(1)
163                     {
164                     menu_tch2();
165                     printf("Please input the option number:\n");            //其余操作肯定都是一样的
166                     scanf("%d",&op_tch);
167                     switch(op_tch)
168                     {
169                     case 0://退出系统
170                         if(file!=-1)    //文件如果开着就给它关了                                                                                               
171                         {
172                             close(file);
173                         }
174                         printf("Exited!\n");
175                         printf("Have a nice day!\n");
176                         return 0;
177                     case 1://开辟空间
178                         printf("Infomalloc:\n");
179                         printf("How many rows shall the hash table have?\n");
180                         scanf("%d",&n);
181                         infomalloc2(&ht1,&ht1_head,n);
182                         break;
183                     case 2://添加学生信息
184                         printf("Add:\n");
185                         printf("Please input the information of this student:\n");
186                         printf("Name:\n");
187                         scanf("%s",stu1.Name);
188                         printf("Gender:\n");
189                         scanf("%s",stu1.Gender);
190                         printf("ID:\n");
191                         scanf("%s",stu1.ID);
192                         printf("Grade:\n");
193                         scanf("%s",stu1.Grade);
194                         printf("Entry completed!\n");
195                         add2(ht1_head,&ln_new,stu1);
                            sprintf(sss,"%s.txt",stu1.Name);
196                         file = open(sss,O_RDWR | O_CREAT | O_TRUNC,0664);
197                         j = write(file,&stu1,sizeof(data_type));
198                         if(j==-1)
199                         {
200                             printf("write failed!\n");
201                             return -1;
202                         }
203                         printf("write completed!\n");
204                         break;
205                     case 3://修改学生信息
206                         printf("Modify:\n");
207                         printf("Please input modified information of this student:\n");
208                         printf("Name:\n");
209                         scanf("%s",stu1.Name);
210                         printf("Gender:\n");
211                         scanf("%s",stu1.Gender);
212                         printf("ID:\n");
213                         scanf("%s",stu1.ID);
214                         printf("Grade:\n");
215                         scanf("%s",stu1.Grade);
216                         printf("Entry completed!\n");
217                         modify2(ht1_head,stu1);
218                         break;
219                     case 4://查找学生信息
220                         printf("Search:\n");                                                                                                                   
221                         printf("Please input the ID code of the student you want to seek:\n");
222                         scanf("%s",ID);
223                         ln0 = search2(ht1_head,ID);
224                         if(ln0 != NULL)
225                         {
226                             printf("The student's information is as follows:\n");
227                             printf("Name:%s\n",ln0->stu_data.Name);
228                             printf("Gender:%s\n",ln0->stu_data.Gender);
229                             printf("ID:%s\n",ln0->stu_data.ID);
230                             printf("Grade:%s\n",ln0->stu_data.Grade);
231                         }
232                         break;
233                     case 5://删除学生信息
234                         printf("Delete:\n");
235                         printf("Please input the ID code of the student you want to delete:\n");
236                         scanf("%s",ID);
237                         delete2(&ht1_head,ID);//子函数里实现查找并释放空间
238                         break;
239                     case 6://增扩空间
240                         printf("Expand:\n");
241                         printf("How many rows do you want to expand?\n");
242                         scanf("%d",&m);
243                         expand2(ht1,&ht1_head,m,n);
244                         break;
245                     case 999://!!!格式化!!!
246                         printf("formatting...\n");
247                         formatting2(&ht1_head,&ht1);
248                         break;
249                     default://错误码提示
250                         printf("Please check your option number!\n");
251                     }
252                     }                                                                                                                                          
253                 }
254 
255                 else
256                 {
257                     printf("请检查操作数!\n");
258                     printf("Please check your option number!\n");
259                 }
260 
261                 break;      //还在循环里面,完成用户功能之后要break跳出去
262             }
263         }//for
264 
265     }//if 教师
266 
267     //从这里开始学生的操作步骤,因为没有认证,功能也少,相对就简单一些
268     else if(a==2)
269     {
270         printf("请选择菜单语言\n");
271         printf("Chose the menu language.\n");
272         printf("1---------中文\n");
273         printf("2---------English\n");
274         scanf("%d",&op_stu_l);
275         if(op_stu_l==1)             //用户选择中文菜单
276         {
277             while(1)
278             {
279                 menu_stu1();
280                 printf("请输入操作数:\n");
281                 scanf("%d",&op_stu);
282                 switch(op_stu)
283                 {
284                 case 0:                                                                                                                                        
285                     //格式化
286                     formatting1(&ht1_head,&ht1);
287                     //顺便关闭一下文件
288                     if(file!=-1)
289                     {
290                         close(file);
291                     }
292                     printf("已退出!\n");
293                     printf("祝您生活愉快!\n");
294                     return 0;
295                 case 1://学生查找信息,这其实是一个综合性的大步骤,因为项目都是黑匣子,我    
                          不需要用户具体地去做每一步,我直接一步到位,一个按钮即完成查找。
296                     printf("请输入想要查找的学生姓名:\n");
297                     scanf("%s",stu1.Name);
298                     sprintf(sss,"%s.txt",stu1.Name);
299                     //打开文件
300                     file = open(sss,O_RDWR);
301                     if(file==-1)
302                     {
303                         printf("该学生不存在\n");
304                         return -1;
305                     }
306                     //获取文件中的数据
307                     //读到data_type类型的stu1里面去
308                     g=read(file,&stu1,sizeof(data_type));
309                     if(g==-1)
310                     {
311                         printf("读取失败\n");
312                         return -1;
313                     }
314                     n=10;
315                     infomalloc(&ht1,&ht1_head,n);
316                     add1(ht1_head,&ln_new,stu1);                                                                                                           
317                   
318           
319                      
320                   
321                         
322                    
323                    
324                     //现在正常查找即可。
325               
326                 
327                     ln0 = search1(ht1_head,stu1.ID);                                                                                                                
328                     if(ln0 != NULL)
329                     {
330                         printf("该学生的信息如下:\n");
331                         printf("姓名:%s\n",ln0->stu_data.Name);
332                         printf("性别:%s\n",ln0->stu_data.Gender);
333                         printf("学号:%s\n",ln0->stu_data.ID);
334                         printf("成绩:%s\n",ln0->stu_data.Grade);
335                         putchar('\n');
336                         printf("信息有误?点我反馈老师\n");
337                     }
338                     break;
339                 default:
340                     printf("请检查操作数!\n");
341                 }
342             }//while
343         }
344         else if(op_stu_l==2)        //用户选择英文菜单
345         {
346             while(1)
347             {
348                 menu_stu2();
349                 printf("Please input the option number!\n");
350                 scanf("%d",&op_stu);
351                 switch(op_stu)
352                 {
353                 case 0:
354                     formatting2(&ht1_head,&ht1);
355                     if(file!=-1)
356                     {
357                         close(file);
358                     }
359                     printf("Exited!\n");                                                                                                                       
360                     printf("Have a nice day!\n");
361                     return 0;
362                 case 1:
363                     printf("Please input the name of student you want to check:\n");
364                     scanf("%s",stu1.Name);
365                     sprintf(sss,"%s.txt",stu1.Name);
366                     file = open("student.txt",O_RDWR);
367                     if(file==-1)
368                     {
369                         printf("This student doesn't exist!\n");
370                         return -1;
371                     }
372                     g=read(file,&stu1,sizeof(data_type));  
373                     if(g==-1) 
374                     {  
375                        printf("read failed!\n");
376                        return -1;
377                     }   
378                     n=10;
379                     infomalloc(&ht1,&ht1_head,n);
380                     add2(ht1_head,&ln_new,stu1);
381                    
382                     
383                     
384                     ln0 = search2(ht1_head,ID);
385                     if(ln0 != NULL)
386                     {
387                         printf("The student's information is as follows:\n");
388                         printf("Name:%s\n",ln0->stu_data.Name);
389                         printf("Gender:%s\n",ln0->stu_data.Gender);
390                         printf("ID:%s\n",ln0->stu_data.ID);
391                         printf("Grade:%s\n",ln0->stu_data.Grade);                                                                                              
392                     }
393                     break;
394                 default:
395                     printf("Please check your option number!\n");
396                 }
397             }
398 
399         }//英文菜单的尾括号
400         else 
401         {
402             printf("请检查操作数!\n");
403             printf("Please check your number!\n");
404         }
405 
406     }//学生的步骤
407 
408     else 
409     {
410         printf("Please check your number!\n");
411     }
412     return 0;
413 }//主函数
                                                                                                                                  
                                                                                                                            

                                                                                                                                                           
                                                                                                                                

                                                                                                                                                           

2.菜单函数,交互界面(menu.c)


  1 #include "../include/main.h"                                                                                                                                   
  2 
  3 void menu_tch1()
  4 {
  5     putchar('\n');
  6     printf("\t ------------------------------------\n");
  7     printf("\t|  欢迎来到某某高校学生信息管理系统  |\n");
  8     printf("\t|                                    |\n");
  9     printf("\t|       1--------开辟空间            |\n");
 10     printf("\t|       2--------添加学生信息        |\n");
 11     printf("\t|       3--------修改学生信息        |\n");
 12     printf("\t|       4--------查找学生信息        |\n");
 13     printf("\t|       5--------删除学生信息        |\n");
 14     printf("\t|       6--------增扩空间            |\n");
 15     printf("\t|       0--------退出系统            |\n");
 16     printf("\t|                                    |\n");
 17     printf("\t|    999--------!!!格式化!!!   |\n");
 18     printf("\t ------------------------------------\n");
 19 }
 20 void menu_tch2()
 21 {
 22     putchar('\n');
 23     printf("\t --------------------------------------------\n");
 24     printf("\t|    Welcome to the XXX university's MSSI    |\n");
 25     printf("\t|                                            |\n");
 26     printf("\t|           1--------infomalloc              |\n");
 27     printf("\t|           2--------Add student             |\n");
 28     printf("\t|           3--------Modify student's info   |\n");
 29     printf("\t|           4--------Search student          |\n");
 30     printf("\t|           5--------Delete student          |\n");
 31     printf("\t|           6--------Expand space            |\n");
 32     printf("\t|           0--------Quit                    |\n");
 33     printf("\t|                                            |\n");
 34     printf("\t|        999--------!!!formatting!!!   |\n");
 35     printf("\t --------------------------------------------\n");
 36 }
 37 void menu_stu1()
 38 {                                                                                                                                                              
 39     putchar('\n');
 40     printf("\t ------------------------------------\n");
 41     printf("\t|  欢迎来到某某高校学生信息管理系统  |\n");
 42     printf("\t|                                    |\n");
 43     printf("\t|         1--------查询信息          |\n");
 44     printf("\t|         0--------退出              |\n");
 45     printf("\t|                                    |\n");
 46     printf("\t ------------------------------------\n");
 47 }
 48 void menu_stu2()
 49 {
 50     putchar('\n');
 51     printf("\t --------------------------------------------\n");
 52     printf("\t|    Welcome to the XXX university's MSSI    |\n");
 53     printf("\t|                                            |\n");
 54     printf("\t|           1--------Search student's info   |\n");
 55     printf("\t|           0--------Quit                    |\n");
 56     printf("\t|                                            |\n");
 57     printf("\t --------------------------------------------\n");
 58 }

                                                                                                                                                           

3.开辟空间(infomalloc.c)


  1 #include "../include/main.h"                                                                                                                                   
  2 
  3 //开辟空间
  4 //参数1:指向欲开辟空间首地址的 指针的地址
  5 //参数2:哈希表表头指针 的地址
  6 //参数3:欲开辟的单元格数量
  7 int infomalloc1(link_node *** ht1,ht ** ht1_head,int n)
  8 {
  9     if(ht1==NULL)
 10     {
 11         printf("空指针错误!\n");
 12         return -1;
 13     }
 14     if(ht1_head==NULL)
 15     {
 16         printf("空指针错误!\n");
 17         return -1;
 18     }
 19     if(n==0 || n<0)
 20     {
 21         printf("请检查你的行数!\n");
 22         return -1;
 23     }
 24     //开辟哈希表的空间
 25     *ht1 = (link_node**)malloc(n * sizeof(link_node));
 26     if(*ht1==NULL)
 27     {
 28         printf("申请空间失败!\n");
 29         return -1;
 30     }
 31     printf("申请空间成功!\n");
 32     //哈希表的初始化
 33     int i = 0;
 34     for(;i<n;i++)
 35     {
 36         (*ht1)[i]=NULL;     //指针数组的初始化
 37     }
 38 //  printf("哈希表初始化完成!\n"); //留下面一句提示即可,保证系统的可适性                                                                                     
 39 
 40     //开辟哈希表表头的空间
 41     *ht1_head = (ht*)malloc(sizeof(ht));
 42     if(*ht1_head==NULL)
 43     {
 44         printf("申请空间失败!\n");
 45         return -1;
 46     }
 47     printf("申请空间成功!\n");
 48     //哈希表表头的初始化
 49     (*ht1_head)->pArr = *ht1;
 50     (*ht1_head)->count = n;     //申请了几个单元格的空间count就为几
 51 
 52     printf("表格初始化完成!\n");
 53 
 54     return 0;
 55 }
 56 
 57 int infomalloc2(link_node *** ht1,ht ** ht1_head,int n)
 58 {
 59     if(ht1==NULL)
 60     {
 61         printf("NULL Error!\n");
 62         return -1;
 63     }
 64     if(ht1_head==NULL)
 65     {
 66         printf("NULL Error!\n");
 67         return -1;
 68     }
 69     if(n==0 || n<0)
 70     {                                                                                                                                                          
 71         printf("Please check your row number\n");
 72         return -1;
 73     }
 74     //开辟哈希表的空间
 75     *ht1 = (link_node**)malloc(n * sizeof(link_node));
 76     if(*ht1==NULL)
 77     {
 78         printf("malloc failed!\n");
 79         return -1;
 80     }
 81     printf("malloc succeeded!\n");
 82     //哈希表的初始化
 83     int i = 0;
 84     for(;i<n;i++)
 85     {
 86         (*ht1)[i]=NULL;     //指针数组的初始化
 87     }
 88     printf("The hash table has been initialized!\n");
 89 
 90     //开辟哈希表表头的空间
 91     *ht1_head = (ht*)malloc(sizeof(ht));
 92     if(*ht1_head==NULL)
 93     {
 94         printf("malloc failed!\n");
 95         return -1;
 96     }
 97     printf("malloc succeeded!\n");
 98     //哈希表表头的初始化
 99     (*ht1_head)->pArr = *ht1;
100     (*ht1_head)->count = n;     //申请了几个单元格的空间count就为几
101     printf("The head of hash table has been initialized!\n");
102                                                                                                                                                                
103     return 0;
104 }

                                                                                                                                                           
                                                                                                                               

                                                                                                                                                           


4.添加学生信息(add.c)


  1 #include "../include/main.h"                                                                                                                                   
  2 
  3 //添加学生信息
  4 //添加到哪里?
  5 //参数1:哈希表的地址,传表头和表均可。
  6 //添加什么?
  7 //参数2:指向一个链表节点的指针 的地址,传地址是因为我要修改它,即link_node ** stu_new
  8 //参数3:学生的个人信息,在外面即初始化完毕,是一个结构体,也是链表的数据域
  9 int add1(ht * ht1_head,link_node ** ln_new,data_type stu1)
 10 {
 11     if(ht1_head==NULL)
 12     {
 13         printf("表格不存在!\n");
 14         return -1;
 15     }
 16     if(ln_new==NULL)
 17     {
 18         printf("空指针错误!\n");
 19         return -1;
 20     }
 21     //初始化链表节点
 22     *ln_new = (link_node*)malloc(sizeof(link_node));
 23     if(*ln_new==NULL)
 24     {
 25         printf("申请空间失败!\n");
 26         return -1;
 27     }
 28     memset(&(*ln_new)->stu_data,0,sizeof(data_type));//数据域写空
 29     (*ln_new)->pNext = NULL;//指针域置空
 30     (*ln_new)->stu_data = stu1;//在该链表节点的数据域写值
 31     //通过哈希函数求得在表中的位置
 32     int pos = hash_func(stu1.ID);
 33     //重链接
 34     (*ln_new)->pNext = ht1_head->pArr[pos];//保护后面的节点
 35     ht1_head->pArr[pos] = *ln_new;
 36 
 37     putchar('\n');
 38     printf("学生信息已录入!\n");
 39     return 0;
 40 }
 41 
 42 int add2(ht * ht1_head,link_node ** ln_new,data_type stu1)
 43 {
 44     if(ht1_head==NULL)
 45     {
 46         printf("The hash table doesn't exist!\n");
 47         return -1;
 48     }
 49     if(ln_new==NULL)
 50     {
 51         printf("NULL Error!\n");
 52         return -1;
 53     }
 54     //初始化链表节点
 55     *ln_new = (link_node*)malloc(sizeof(link_node));
 56     if(*ln_new==NULL)
 57     {
 58         printf("malloc failed!\n");
 59         return -1;                                                                                                                                             
 60     }
 61     memset(&(*ln_new)->stu_data,0,sizeof(data_type));//数据域写空
 62     (*ln_new)->pNext = NULL;//指针域置空
 63     (*ln_new)->stu_data = stu1;//在该链表节点的数据域写值
 64     //通过哈希函数求得在表中的位置
 65     int pos = hash_func(stu1.ID);
 66     //重链接
 67     (*ln_new)->pNext = ht1_head->pArr[pos];//保护后面的节点
 68     ht1_head->pArr[pos] = *ln_new;
 69 
 70     putchar('\n');                                                                                                                                             
 71     printf("The information of this student has been written.\n");
 72     return 0;
 73 }
 74 

                                                                                                                                                           




5.修改学生信息(modify.c)


  1 #include "../include/main.h"                                                                                                                                   
  2 
  3 //修改学生信息
  4 //参数1:哈希表的地址
  5 //参数2:学生的个人信息,stu1
  6 int modify1(ht * ht1_head,data_type stu1)
  7 {
  8     link_node * ln_mod = search1(ht1_head,stu1.ID);
  9     if(ln_mod==NULL)
 10     {
 11         printf("修改失败!\n");
 12         return -1;
 13     }
 14     else
 15     {
 16         ln_mod->stu_data = stu1;
 17         printf("修改成功!\n");
 18         return 0;
 19     }
 20 }
 21 
 22 int modify2(ht * ht1_head,data_type stu1)
 23 {
 24     link_node * ln_mod = search2(ht1_head,stu1.ID);
 25     if(ln_mod==NULL)
 26     {
 27         printf("madification failed!\n");
 28         return -1;
 29     }
 30     else
 31     {
 32         ln_mod->stu_data = stu1;
 33         printf("modification completed!\n");
 34         return 0;
 35     }
 36 }
 37                                                                                                                                                                

                                                                                                                                                           


                                                                                                                                                           

6.查找学生信息(search.c)


  1 #include "../include/main.h"                                                                                                                                   
  2 
  3 //查找学生信息
  4 //按照我上面的哈希算法以及我的ID取值,
  5 //我的哈希表将是一个(n+m)行,不超过2列的表,也就是说没有冲突。
  6 //所以检索条件是  单元格内地址不为空即可。
  7 //如果不为空,用户可能还想要查看里面节点的数据域,而不是简单看一下有没有就完了。
  8 //所以返回值是一个地址。
  9 link_node * search1(ht * ht1_head,char * ID)
 10 {
 11     int pos = hash_func(ID);//根据ID索引到哈希表的具体位置
 12     if( ht1_head->pArr[pos] == NULL )
 13     {
 14         printf("没有该学生!\n");
 15         return NULL;
 16     }
 17     else
 18     {
 19         printf("检索到该学生!\n");
 20 
 21         return ht1_head->pArr[pos]; //返回该学生在内存空间的地址!
 22     }
 23 
 24 
 25 }
 26 
 27 link_node * search2(ht * ht1_head,char * ID)
 28 {
 29     int pos = hash_func(ID);//根据ID索引到哈希表的具体位置
 30     if( ht1_head->pArr[pos] == NULL )
 31     {
 32         printf("No such student!\n");
 33         return NULL;                                                                                                                                           
 34     }
 35     else
 36     {
 37         printf("There is such a student!\n");
 38         return ht1_head->pArr[pos]; //返回该学生在内存空间的地址!
 39     }
 40 }


7.删除学生信息(delete.c)


  1 #include "../include/main.h"
  2                                                                                                                                                                
  3 //输入学生ID实现删除
  4 //参数1:查找的范围,也就是哈希表的地址
  5 //参数2:学生的ID
  6 int delete1(ht ** ht1_head,char * ID)
  7 {
  8     int pos = hash_func(ID);//获取在哈希表的哪一行
  9 
 10     //发现通过调用search2就能实现返回一个想找寻学生节点地址,那么调用它
 11     link_node * ln_del = search1(*ht1_head,ID);
 12 
 13     //此处可以选择清空该链表节点,也可以选择不清空,因为按照良好的编程习惯,下次启用该片空间时,肯定会手动清空的。
 14     memset(&(ln_del->stu_data),0,sizeof(data_type));
 15 
 16     (*ht1_head)->pArr[pos] = ln_del->pNext; //保护后面的节点
 17 
 18     free(ln_del);//通过ln_del来释放这片空间
 19     ln_del = NULL;
 20     printf("已删除该学生信息!\n");
 21     return 0;
 22 }
 23 
 24 int delete2(ht ** ht1_head,char * ID)
 25 {
 26     int pos = hash_func(ID);//获取在哈希表的哪一行
 27 
 28     //发现通过调用search2就能实现返回一个想找寻学生节点地址,那么调用它
 29     link_node * ln_del = search2(*ht1_head,ID);
 30 
 31     //此处可以选择清空该链表节点,也可以选择不清空,因为按照良好的编程习惯,下次启用该片空 
        间时,肯定会手动清空的。
 32     memset(&(ln_del->stu_data),0,sizeof(data_type));
 33                                                                                                                                                                
 34     (*ht1_head)->pArr[pos] = ln_del->pNext; //保护后面的节点
 35 
 36     free(ln_del);//通过ln_del来释放这片空间
 37     ln_del = NULL;
 38     printf("delete completed!\n");
 39     return 0;
 40 }




8.增扩空间(expand.c)


  1 #include "../include/main.h"
  2 
  3 //增扩空间,可以用realloc。
  4 //参数1:指向原有哈希表的指针 的地址,即&ht1。     
  5 //参数2:哈希表表头指针 的地址,即&ht1_head。
  6 //参数3:增扩的单元格数
  7 //参数4:原来已有的单元格数,用来计算增扩的起始地址,增扩一定是在开辟了之后,那么就用之前的n
  8 int expand1(link_node ** ht1,ht ** ht1_head,int m,int n)
  9 {
 10     if(ht1==NULL)   //检查参数1
 11     {
 12         printf("表格不存在!\n");
 13         return -1;
 14     }                                                                                                                                                          
 15     if(ht1_head==NULL)  //检查参数2
 16     {
 17         printf("空指针错误!\n");
 18         return -1;
 19     }
 20     if(n==0)    //这一步是为了增强程序的鲁棒性
 21     {
 22     //  printf("Dangerous!!! Prerequisite doesn't exist.\n");
 23         return -1;
 24     }
 25     if(m==0 || m<0) //检查参数3
 26     {
 27     //  printf("Are you serious???\n");
 28         printf("请检查你的输入数!\n");
 29         return -1;
 30     }
 31 
 32 //  *ht1 = (*ht1)+n;    //将哈希表的指针向后移动n个链表节点
 33 
 34     //现在ht1已指向我想要开辟的位置
 35     ht1 = (link_node**)realloc(ht1,(m+n)*sizeof(link_node));//这一步即增扩m个链表节点的空间
 36     if(ht1==NULL)                                                                                                                                              
 37     {
 38         printf("申请空间失败!\n");
 39         return -1;
 40     }
 41     //再修改一下表头的count数据即可
 42     (*ht1_head)->count = n+m;
 43 
 44     printf("增扩空间完毕!\n");
 45     return 0;
 46 }
 47 
 48 int expand2(link_node ** ht1,ht ** ht1_head,int m,int n)
 49 {
 50     if(ht1==NULL)   //检查参数1
 51     {
 52         printf("The hash table doesn't exist!\n");
 53         return -1;
 54     }
 55     if(ht1_head==NULL)  //检查参数2
 56     {
 57         printf("NULL Error!\n");
 58         return -1;
 59     }
 60     if(n==0)    //这一步是为了增强程序的鲁棒性
 61     {
 62         printf("Dangerous!!! Prerequisite doesn't exist.\n");
 63         return -1;                                                                                                                                             
 64     }
 65     if(m==0 || m<0) //检查参数3
 66     {
 67         printf("Are you serious???\n");
 68         printf("Please check your number\n");
 69         return -1;
 70     }
 71 
 72 //  *ht1 = (*ht1)+n;    //将哈希表的指针向后移动n个链表节点
 73     //现在ht1已指向我想要开辟的位置
 74     ht1 = (link_node**)realloc(ht1,(m+n)*sizeof(link_node));//这一步即增扩m个链表节点的空间
 75     if(ht1==NULL)
 76     {
 77         printf("malloc failed!\n");
 78         return -1;
 79     }
 80     //再修改一下表头的count数据即可
 81     (*ht1_head)->count = n+m;
 82 
 83     printf("Expansion completed!\n");
 84     return 0;
 85 }




 9.格式化空间(formatting.c)


  1 #include "../include/main.h"
  2 
  3 //!!!格式化!!!
  4 //释放并清空哈希表的所占空间
  5 int formatting1(ht ** ht1_head,link_node *** ht1)
  6 {
  7     if(*ht1_head==NULL || *ht1==NULL)
  8     {
  9         printf("表格不存在!\n");
 10         return -1;
 11     }
 12 
 13     link_node * ln_des = NULL;//创建一个指向某一链表节点的指针变量,准备头删
 14 //  ln_des = (*ht1_head)->pArr[0];
 15     int i;
 16     for(i=0;i<((*ht1_head)->count);i++)
 17     {
 18         while(ln_des!=NULL)
 19         {
 20             //先让指针变量指向哈希表第一个单元格的后面第一个链表节点,可以简单理解为哈希表第一行链表的首节点
 21             ln_des = (*ht1_head)->pArr[i];
 22             //按照惯例,保护后面的节点,但其实我这种哈希算法其实是没有冲突的,这里可以不保护
 23             (*ht1_head)->pArr[i] = ln_des->pNext;
 24             free(ln_des);
 25         }//第i行清理完毕
 26 
 27         //释放第i个单元格的空间                                                                                                                                
 28         free((*ht1_head)->pArr[i]);
 29         (*ht1_head)->pArr[i] = NULL;
 30     }
 31         ln_des = NULL;
 32 
 33     //现在哈希表是一个全部为空指针的指针数组
 34     //还需要释放原来 指向哈希表的指针 ht1 以及 哈希表表头指针 ht1_head对应的空间
 35     //并把其置空
 36     free(*ht1);                                                                                                                                                
 37     *ht1 = NULL;
 38     free(*ht1_head);
 39     *ht1_head = NULL;
 40 
 41     printf("格式化完毕!\n");
 42     return 0;
 43 }
 44 
 45 int formatting2(ht ** ht1_head,link_node *** ht1)
 46 {
 47     if(*ht1_head==NULL || *ht1==NULL)
 48     {
 49         printf("The hash table doesn't exist!\n");
 50         return -1;
 51     }
 52 
 53     link_node * ln_des = NULL;//创建一个指向某一链表节点的指针变量,准备头删
 54     int i;
 55     for(i=0;i<(*ht1_head)->count;i++)
 56     {
 57         while(ln_des!=NULL)
 58         {
 59             //先让指针变量指向哈希表第一个单元格的后面第一个链表节点,可以简单理解为哈希表第一行链表的首节点
 60             ln_des = (*ht1_head)->pArr[i];
 61             //按照惯例,保护后面的节点,但其实我这种哈希算法其实是没有冲突的,这里可以不保护
 62             (*ht1_head)->pArr[i] = ln_des->pNext;
 63             free(ln_des);
 64             ln_des = NULL;
 65         }//第i行清理完毕
 66                                                                                                                                                                
 67         //释放第i个单元格的空间
 68         free((*ht1_head)->pArr[i]);
 69         (*ht1_head)->pArr[i] = NULL;
 70     }
 71 
 72     //现在哈希表是一个全部为空指针的指针数组
 73     //还需要释放原来 指向哈希表的指针 ht1 以及 哈希表表头指针 ht1_head对应的空间
 74     //并把其置空
 75     free(*ht1);
 76     *ht1 = NULL;
 77     free(*ht1_head);
 78     *ht1_head = NULL;
 79 
 80     printf("formatting completed!\n");
 81     return 0;
 82 }
 83 





10.哈希函数(hash_func.c)

  1 #include "../include/main.h"
  2 
  3 //哈希算法根据数据而定.
  4 //我的数据是学生的学号,我打算给一组 连续的100,101,102...这样的数字
  5 //那么我对100取余数就能得到一个地址。
  6 //
  7 //值得一提的是,按照个人ID号码去取哈希地址的话,因为ID数据高度相似 取值连续 且 绝不重复,
  8 //所以在对ID进行索引的前提下,只要哈希算法足够科学,完全能做到哈希表索引不冲突。
  9 int hash_func(char * ID)
 10 {
 11     int i = atoi(ID);//就是一个字符型数字到整形数字的转化,可以man一下
 12     return (i%100);
 13 }
 14                                                                                                                                                                

三、待优化点:

1.

 在修改学生信息的时候,可以减少用户的操作数,比如,可以减少录入修改信息的条数,只录入欲修改的信息。

2.

格式化按钮可以增加二次确认。

3.

另外,我所做的双语版本其实就是把(所有函数和选择)里面的提示语都做了一个第二语言版本,

如果我习惯不在子函数里写提示语,而是在主函数调用时根据执行的情况(子函数的返回值)去写提示语,或许可以不必写两遍子函数,代码量可以减半。

但这并不是我的编程习惯,不做优化。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值