数据结构(c语言)之学生信息管理系统
程序思维导图
代码表示(代码参考:长春大学-牛言涛老师)
如有错误请指出欢迎交流
1 #include<stdio.h> 2 #include<malloc.h>//动态存储分配函数头文件 3 #include<math.h>//包含数学函数的文件 4 #include<string.h>//一个和字符串处理相关的头文件 5 #include<process.h>//包含用于和宏指令的作用声明与螺纹和过程一起使用的C标头文件 6 #define ERROR 0 //宏定义 7 #define OK 1 8 #define over -2 9 #define ListInitSize 20 10 #define ListIncrement 5 11 #define Namelen 8 12 #define Majorlen 20 13 #define INIT_N 3 14 typedef int Status; //自定义类型语句 Status i 等价于 int i 15 typedef char StatusC; 16 17 typedef struct{ 18 StatusC number[10]; //学号:081330385 19 StatusC name[Namelen+1]; //姓名:郭靖 20 StatusC gender; //性别:男 21 StatusC telephone[12]; //电话:15890377853 22 StatusC qqNumber[13]; //QQ:485284320 23 StatusC major[Majorlen+1];//专业:计算机科学与技术 24 25 }Student;//类型为学生 26 27 typedef struct{ 28 29 Student *elem; //存储空间的基址 30 Status length; //当前长度 31 Status listsize; //当前分配的存储容量(以sizeof(Studnet)为单位) 32 }Sqlist; 33 34 //信息初始化,构造一个空的线性表 35 Status InitList(Sqlist &l){ 36 37 l.elem=(Student *)malloc(ListInitSize*sizeof(Student)); 38 //申请LIST_INIT_SIZE个大小为整型(Student)字节的空间, 39 //把空间指针给L.elem 40 if(!l.elem)exit(over); 41 //判断l中的数据成员elem是否为0,为0即执行if下面语句 42 l.length=0; 43 //赋值 44 l.listsize=ListInitSize; 45 return OK; 46 } 47 48 //插入记录 49 Status ListInsert(Sqlist &l,Status i,Student s){ 50 51 Student *newbase; 52 if(i<1||i>l.length+1) 53 return ERROR;//i值不合法 54 if(l.length>=l.listsize)//当前存储空间已经满了,增加分配空间 55 { 56 newbase=(Student*)realloc(l.elem,( 57 ListInitSize+ListIncrement)*(sizeof(Student))); 58 /* 59 先释放原来L.elem所指内存区域,并按照 60 (LIST_INIT_SIZE+ListIncrement)*sizeof(Student) 61 的大小重新分配空间其中ListIncrement为20, 62 同时将原有数据从头到尾拷贝到新分配的内存区域, 63 并返回该内存区域的首地址。即重新分配存储器块。 64 */ 65 if(!newbase)exit(over); 66 // 判断newbase是否为0,为0即执行if下面语句 67 l.elem=newbase; 68 //赋值 69 l.listsize+=ListIncrement; 70 } 71 for(Status j=l.length;j>=i;j--) 72 l.elem[j]=l.elem[j-1]; 73 //赋值 74 l.elem[i-1]=s; 75 l.length++; 76 return OK; 77 } 78 79 //打印输出线性表中的信息 80 void print(Sqlist &l){ 81 82 if(l.length==0) 83 printf("空表,无任何记录!\n\n"); 84 printf("学号 姓名 性别 手机号 QQ 专业\n"); 85 printf("******************************\n"); 86 87 for(Status i=0;i<l.length;i++){ 88 89 printf("%-10s %-8s",l.elem[i].number,l.elem[i].name); 90 //输出学好 姓名 91 if(l.elem[i].gender=='m')printf("男"); 92 //判断语句 93 else printf("女"); 94 printf("%14s %9s %10s",l.elem[i].telephone,l.elem[i].qqNumber,l.elem[i].major); 95 //输出电话号码 qq号码 专业 96 printf("\n"); 97 } 98 printf("------------------------------\n"); 99 } 100 101 //打印输出线性表中指定学生的信息 102 void print_single(Student s){ 103 104 printf("学号 姓名 性别 手机号 QQ 专业\n"); 105 printf("******************************\n"); 106 printf("%-10s %-8s",s.number,s.name); 107 //输出学好 姓名 108 if(s.gender=='m')printf("男"); 109 else printf("女"); 110 printf("%14s %9s %10s",s.telephone,s.qqNumber,s.major); 111 //输出电话号码 qq号码 专业 112 printf("\n"); 113 printf("------------------------------\n"); 114 } 115 116 //接受键盘输入信息 117 void ScanIn(Sqlist &l){ 118 119 StatusC a[2]; 120 Status i; 121 printf("\t 您选择插入一条学生记录\n"); 122 do{ 123 Student s; 124 printf("\t 请输入学号:"); 125 scanf("%s",s.number); 126 printf("\t 请输入姓名(<=%d个字符):",Namelen); 127 scanf("%s",s.name); 128 129 printf("\t 请输入电话号码:"); 130 scanf("%s",s.telephone); 131 printf("\t 请输入QQ号:"); 132 scanf("%s",s.qqNumber); 133 printf("\t 请输入专业:"); 134 scanf("%s",s.major); 135 printf("\t 请输入性别:(m:男,f:女)"); 136 scanf("%*c%c",&s.gender); 137 printf("\t 请输入你要插入的位置(1<=i<=%d):",l.length+1); 138 scanf("%d",&i); 139 ListInsert(l,i,s); 140 printf("\t 您想继续插入记录吗?(y/n)\t"); 141 scanf("%s",a); 142 143 }while(strcmp(a,"y")==0||strcmp(a,"Y")==0); 144 //调用strcmp函数 145 } 146 147 //删除通讯中第i条记录 148 Status ListDelete(Sqlist &l,int i,Student s){ 149 150 Status j; 151 if(i<1||i>l.length)return ERROR; 152 //判断 153 else{ 154 155 s=l.elem[i-1]; 156 for(j=i;j<=l.length;j++)l.elem[j-1]=l.elem[j]; 157 l.length--; 158 return OK; 159 } 160 } 161 162 //按照升序排列 163 void SortorderAscend(Sqlist &l){ 164 165 system("cls");//清空前面的信息之输出下面信息 166 Student s; 167 for(Status i=0;i<l.length-1;i++) 168 for(Status j=0;j<l.length-i-1;j++){ 169 //循环比较大小 ,排列顺序 170 if(strcmp(l.elem[j].number,l.elem[j+1].number)>0){ 171 //strcmp() 以二进制的方式进行比较,不会考虑多字节或宽字节字符; 172 //用来比较字符串(区分大小写) 173 s=l.elem[j]; 174 l.elem[j]=l.elem[j+1]; 175 l.elem[j+1]=s; 176 } 177 } 178 printf("*****按照升序排序成功!******\n\n"); 179 } 180 181 //判断姓名是否相同 182 Status EqualName(Student s1,Student s2){ 183 184 if(strcmp(s1.name,s2.name))return ERROR; 185 //比较两个字符串是否相同 186 else return OK; 187 } 188 189 //定位某个元素 190 int LocateElem(Sqlist l,Student s,Status(*compare)(Student,Student)) { 191 192 Status i=1; 193 Student *p=l.elem; 194 while(i<=l.length&&!compare(*p++,s))i++; 195 if(i<=l.length) 196 return i; 197 //定位元素的位置 198 else 199 return 0; 200 } 201 202 //按照姓名查找 203 void searchName(Sqlist l,Status(*equal)(Student,Student)){ 204 205 system("cls");//清空前面的信息之输出下面信息 206 Student s; 207 Status j; 208 StatusC a[2]; 209 do{ 210 printf("\t 请输入你要查找的学生的姓名:"); 211 scanf("%s",s.name); 212 j=LocateElem(l,s,equal); 213 if(!j)printf("没有查找到你所要查找的学生记录!\n"); 214 else print_single(l.elem[j-1]); 215 printf("\t 您想继续查找吗?(y/n)\t"); 216 scanf("%s",a); 217 218 }while(strcmp(a,"y")==0||strcmp(a,"Y")==0); 219 } 220 221 //修改姓名 222 void ModifyName(Sqlist &l,Status(*equal)(Student,Student)){ 223 224 system("cls");//清空前面的信息之输出下面信息 225 Student s; 226 Status j; 227 StatusC number_new[10],name_new[Namelen+1],gender_new, 228 telephone_new[12],qqNumber_new[13],major_new[Majorlen+1]; 229 StatusC a[2]; 230 do{ 231 printf("\t 请输入你要更改的学生的姓名:"); 232 scanf("%s",s.name); 233 j=LocateElem(l,s,equal); 234 if(!j)printf("没有查找到你所要查找的学生记录!\n"); 235 else { 236 237 print_single(l.elem[j-1]); 238 Status isOrNo=1; 239 printf("\n修改通讯录:1 学号,2 姓名,3 性别,4 电话,5 QQ号,6 专业, 0 取消\n") ; 240 while(isOrNo){ 241 242 printf("--------------------------\n"); 243 printf("请选择需要修改的属性序号:"); 244 scanf("%d",&isOrNo); 245 switch(isOrNo){ 246 247 case 1: 248 printf("请输入更改后的学号:"); 249 scanf("%s",number_new); 250 strcpy(l.elem[j-1].number,number_new); 251 break; 252 case 2: 253 printf("请输入更改后的姓名:"); 254 scanf("%s",name_new); 255 strcpy(l.elem[j-1].name,name_new); 256 break; 257 case 3: 258 printf("请输入更改后的性别:"); 259 scanf("%*c%c",&l.elem[j-1].gender); 260 break; 261 case 4: 262 printf("请输入更改后的电话:"); 263 scanf("%s",telephone_new); 264 strcpy(l.elem[j-1].telephone,telephone_new); 265 break; 266 case 5: 267 printf("请输入更改后的QQ号:"); 268 scanf("%s",qqNumber_new); 269 strcpy(l.elem[j-1].qqNumber,qqNumber_new); 270 break; 271 case 6: 272 printf("请输入更改后的专业:"); 273 scanf("%s",major_new); 274 strcpy(l.elem[j-1].major,major_new); 275 break; 276 277 } 278 } 279 printf("\n****更改后该条记录变为****\n\n"); 280 print_single(l.elem[j-1]); 281 } 282 printf("您想继续修改吗?(y/n)\t"); 283 scanf("%s",a); 284 }while(strcmp(a,"y")==0||strcmp(a,"Y")==0); 285 } 286 287 //主菜单 288 void menu(){ 289 290 system("cls");//清空前面的信息之输出下面信息 291 printf("\t*********************\n"); 292 printf("\t**欢迎使用学生通讯录管理系统**\n"); 293 printf("\t*********************\n"); 294 printf("\t**请选择如下操作,输入序号**\n"); 295 printf("\t 0:退出系统\n"); 296 printf("\t 1:将初始学生记录插入线性表\n"); 297 printf("\t 2:显示线性表中所有内容\n"); 298 printf("\t 3:向线性表中增加一条记录\n"); 299 printf("\t 4:从线性表中删除一条记录\n"); 300 printf("\t 5:按照姓名修改一条记录\n"); 301 printf("\t 6:按照姓名查找一条记录\n"); 302 printf("\t 7:按照学号升序排列通讯录\n"); 303 printf("\t*********************\n"); 304 printf("\t 您想进行什么操作,请选择\n"); 305 306 } 307 308 //主函数 309 int main(){ 310 311 Sqlist l; 312 Status i,select; //select 变量标记用户的选择 313 if(InitList(l)!=OK)printf("\n\t线性表初始化失败!\n"); 314 Student s[INIT_N]={{"081404327","马东",'m',"13729947569","87384747" ,"机械工程"}, 315 {"081404527","李东",'m',"13729985469","84786747" ,"软件工程"}, 316 {"081435797","马西",'f',"12329947569","84735777" ,"通讯工程"}}; 317 menu(); 318 scanf("%d",&select); 319 while(select){ 320 switch(select){ 321 case 1: //初始化数据 322 system("cls");//清空前面的信息之输出下面信息 323 for(i=0;i<INIT_N;i++){ 324 325 if(ListInsert(l,i+1,s[i])!=OK) 326 printf("\t初始化数据失败!\n"); 327 328 } 329 if(i==INIT_N)printf("\t初始化数据成功\n\n"); 330 print(l); 331 printf("\n输入0:退出,输入11:返回主菜单\t"); 332 break; 333 case 2://显示线性表中的记录 334 system("cls");//清空前面的信息之输出下面信息 335 print(l); 336 printf("\n输入0:退出,输入11:返回主菜单\t"); 337 break; 338 case 3://接受键盘输入,并把记录插入到线性表中 339 system("cls");//清空前面的信息之输出下面信息 340 ScanIn(l); 341 system("cls");//清空前面的信息之输出下面信息 342 print(l); 343 printf("\n输入0:退出,输入11:返回主菜单\t"); 344 break; 345 case 4://删除通讯录中某条信息 346 system("cls");//清空前面的信息之输出下面信息 347 Student *s2=l.elem; 348 print(l); 349 printf("您想删除第几条通讯录1~%d:\n",l.length); 350 int k; 351 scanf("%d",&k); 352 Student de_s; 353 system("cls");//清空前面的信息之输出下面信息 354 if(ListDelete(l,k,de_s)==OK){ 355 print(l); 356 printf("\t%-6s 已经删除成功!\n",de_s.name); 357 } 358 printf("\n输入0:退出,输入11:返回主菜单\t"); 359 break; 360 case 5://按照姓名修改一条记录 361 ModifyName(l,EqualName); 362 printf("\n输入0:退出,输入11:返回主菜单\t"); 363 break; 364 case 6://按照姓名查找记录 365 searchName(l,EqualName); 366 printf("\n输入0:退出,输入11:返回主菜单\t"); 367 break; 368 case 7://按照学好升序排列 369 system("cls");//清空前面的信息之输出下面信息 370 SortorderAscend(l); 371 print(l); 372 printf("\n输入0:退出,输入11:返回主菜单\t"); 373 break; 374 case 11://返回主菜单 375 menu(); 376 break; 377 } 378 scanf("%d",&select); 379 } 380 return 0; 381 382 383 }
结果显示
主菜单
将初始学生信息插入线性表中
读取线性表中信息
插入一条学生信息
删除一条学生信息
更改学生信息
查找学生信息
将学生信息排序