本文章是大一时候期末实训写的一个学习笔记,有许多代码都都是参考大佬的代码来写的,删掉了许多功能只有一些基础功能有许多不足和错误之处请大家指正
1 #include<stdio.h> /*I/O函数*/ 2 #include<stdlib.h> /*其它说明*/ 3 #include<string.h> /*字符串函数*/ 4 #define LEN 15 /* 学号和姓名最大字符数,这里设置的是15*/ 5 #define N 200 /* 最大学生人数,200*/ 6 7 /*比较 <> 和 "" 8 <> 直接从系统目录下查找包含这个文件 9 "" 先从工程的项目目录下查找这个,如果没有,再到系统目录下查找 10 */ 11 12 struct record //(record)是一个集合,它把一组相关数据聚集在一个存储单元里,记录中的每个元素称作字段 13 { 14 char code[LEN + 1]; /* 学号 加 1是为了LEN留余,不加1,也没有关系,只要不越界就行了 name相同*/ 15 char name[LEN + 1]; /* 姓名 同上*/ 16 int age; /* 年龄*/ 17 char sex; /* 性别*/ 18 float score[3]; /* 3门课程成绩*/ 19 }stu[N]; //stu[N] 是存放N个元素的数组,数组中的每个元素都是struct record {………………}中的结构体对象 20 21 int k = 1,n = 0, m = 0;/*定义全局变量, n代表当前记录的学生总人数,m为新增加的学生人数*/ 22 23 /*******函数声明********/ 24 25 void readfile(); /* 读入数据*/ 26 27 void seek(); /* 查找信息*/ 28 29 30 void insert(); /* 插入数据*/ 31 32 void display(); /* 显示信息*/ 33 34 void save(); /* 保存信息*/ 35 36 void menu(); /* 菜单*/ 37 38 39 int main() // 主函数 menu读取一个字符 整数,字符在内存中映射为ASCII码 40 41 { 42 while (k) 43 { 44 menu(); 45 } 46 system("pause"); 47 return 0; 48 } 49 50 51 /* 从文件中读取数据到结构体数组*/ 52 void readfile() 53 { 54 char filename[LEN + 1]; /* 文件名*/ 55 FILE* fp; /* 文件指针*/ 56 int i = 0; 57 printf("请输入以存有学生信息的文件名:\n"); 58 scanf("%s", filename); 59 if ((fp = fopen(filename, "r")) == NULL) /* 以只读的方式打开指定文件,:打开文件名为filename的文件,根据fopen的返回值(fp), 60 判断该文件是否打开,如果没有打开,则打印"Error opening file"信息, 61 然后退出程序,如果正确打开,则跳过这里,执行后面的语句,*/ 62 { 63 printf("打开文件%s错误", filename); 64 printf("你需要先选择菜单4增加学生信息\n"); 65 66 system("pause");/* system("PAUSE");和system("pause");用和效果一样,因为dos命令是不区分大小写的。 67 system("PAUSE") 是暂停的意思,等待用户信号;不然控制台程序会一闪即过,你来不及看到执行结果。 */ 68 69 return; 70 } 71 /* 循环读入学生信息*/ 72 while (fscanf(fp, "%s%s%d%c%f%f%f", stu[i].code, stu[i].name, &stu[i].age, &stu[i].sex, &stu[i].score[0], &stu[i].score[1], &stu[i].score[2]) == 7) 73 { 74 i++; 75 } 76 n = i; 77 if (0 == i) 78 printf("文件为空,你需要先选择菜单4增加学生信息\n"); 79 else 80 printf("读入成功\n"); 81 fclose(fp); 82 system("pause"); 83 } 84 85 86 /* 查找信息*/ 87 void seek() /*查找*/ 88 { 89 int i, item, flag; 90 char s1[21]; /* 以姓名和学号最长长度+1为准 :LEN+1 防止越界 chars1[]是一个字符串变量,可 91 以被修改,s1 是函数的栈空间区域,函数执行完成,这个空间就没了*/ 92 printf("------------------\n"); 93 printf("-----1.按学号查询-----\n"); 94 printf("-----2.按姓名查询-----\n"); 95 printf("-----3.退出本菜单-----\n"); 96 printf("------------------\n"); 97 while (1)//while(0)表示不执行循环语句,while(1)表示执行语句。防止越界 98 { 99 printf("请选择子菜单编号:"); 100 scanf("%d", &item); 101 flag = 0; //给变量赋值 102 switch (item) //此处的item为我们输入的菜单选项通过switch判断选择代码。其功能就是控制流程流转的 103 { 104 case 1: 105 printf("请输入要查询的学生的学号:\n"); 106 scanf("%s", s1); 107 for (i = 0; i < n; i++) 108 if (strcmp(stu[i].code, s1) == 0) 109 { 110 flag = 1; 111 printf("学生学号 学生姓名 年龄 性别 C语言成绩 高等数学 大学英语成绩\n"); 112 printf("--------------------------------------------------------------------\n"); 113 printf("%6s %7s %6d %6c %9.1f %10.1f %10.1f\n", stu[i].code, stu[i].name, stu[i].age, stu[i].sex, stu[i].score[0], stu[i].score[1], stu[i].score[2]); 114 } 115 if (0 == flag) 116 printf("该学号不存在!\n"); break; 117 case 2: 118 printf("请输入要查询的学生的姓名:\n"); 119 scanf("%s", s1); 120 for (i = 0; i < n; i++) 121 if (strcmp(stu[i].name, s1) == 0) 122 { 123 flag = 1; 124 printf("学生学号 学生姓名 年龄 性别 C语言成绩 高等数学 大学英语成绩\n"); 125 printf("--------------------------------------------------------------------\n"); 126 printf("%6s %7s %6d %6c %9.1f %10.1f %10.1f\n", stu[i].code, stu[i].name, stu[i].age, stu[i].sex, stu[i].score[0], stu[i].score[1], stu[i].score[2]); 127 } 128 if (0 == flag) 129 printf("该姓名不存在!\n"); break; 130 case 3:return; //返回上一级 131 default:printf("请在1-3之间选择\n");//default只有在case匹配失败的时候才会执行 132 } 133 } 134 } 135 136 137 void sort()/*按学号排序 此处通过比较排序法(最基础的挨个比较)运算量要比其他排序法时间复杂度要高但稳定性要比较好一点复杂度简单*/ 138 { 139 int i = 0, j = 0; 140 int tmp = 0; 141 printf("测试 j :\n", atoi(stu[j].code)); 142 printf("测试 j+1:%d\n", atoi(stu[j+1].code)); 143 for (i = 0; i < n - 1; i++) //冒泡核心,双层for循环 144 { 145 for (j = 0; j < n - 1 - i; j++) 146 { 147 //不能使用strcmp 148 //理由:这个函数是会从左到右一个字符一个字符判断 149 //例子:102 和 20会先判断第一个字符 1 和 2 于是102<20 150 //if (strcmp(stu[j - 1].code, stu[j].code) > 0) 151 if(atoi(stu[j].code)> atoi(stu[j+1].code))//此处决定按从小到大或从大到小 152 { 153 /* 154 c语言有一些函数可以把字符串转为数字 155 atof() 将字符串转换为双精度浮点型值 156 atoi() 将字符串转换为整型值 157 atol() 将字符串转换为长整型值 158 strtod() 将字符串转换为双精度浮点型值,并报告不能被转换的所有剩余数字 159 strtol() 将字符串转换为长整值,并报告不能被转换的所有剩余数字 160 strtoul() 将字符串转换为无符号长整型值,并报告不能被转换的所有剩余数字 161 */ 162 printf("测试 j - 1:\n",atoi(stu[j - 1].code)); 163 printf("测试 j:%d\n",atoi(stu[j].code)); 164 record s; 165 s = stu[j]; 166 stu[j] = stu[j+1]; 167 stu[j+1] = s; 168 } 169 } 170 } 171 } 172 void insert() 173 { 174 int j = n, i, flag;//定义函数 175 176 printf("请输入待增加的学生数:\n");//输入插入学生数量 177 scanf("%d", &m); 178 if (m > 0) 179 { 180 do 181 { 182 flag = 1; 183 while (flag) 184 { 185 flag = 0; 186 printf("请输入第%d位学生的学号:\n", j + 1); 187 scanf("%s", stu[j].code); 188 for (i = 0; i < j; i++) /*进行检查,与之前的学号比较,如果重复,则重新输入*/ 189 if (strcmp(stu[j].code, stu[i].code) == 0) 190 { 191 printf("已有该学号,请重新录入\n"); 192 flag = 1; 193 break; /*如有重复,退出内层循环*/ 194 } 195 } 196 //在前面的while循环内是有输入学号的 197 //printf("请输入第%d 个学生的学号:\n", j + 1); 198 //scanf("%s", stu[j].code); 199 printf("请输入第%d 个学生的姓名:\n", j + 1); 200 scanf("%s", stu[j].name); 201 printf("请输入第%d 个学生的年龄:\n", j + 1); 202 scanf("%d", &stu[j].age); 203 printf("请输入第%d 个学生的性别:\n", j + 1); 204 scanf(" %c", &stu[j].sex); 205 printf("请输入第%d 个学生的C语言成绩\n", j + 1); 206 scanf("%f", &stu[j].score[0]); 207 printf("请输入第%d 个学生的高等数学成绩:\n", j + 1); 208 scanf("%f", &stu[j].score[1]); 209 printf("请输入第%d 个学生的大学英语成绩:\n", j + 1); 210 scanf("%f", &stu[j].score[2]); 211 if (0 == flag) 212 { 213 j++; 214 } 215 } while (j < n + m); 216 } 217 n += m; 218 printf("信息增加完毕!\n\n"); 219 220 system("pause"); 221 } 222 223 224 /* 显示信息*/ 225 void display() 226 { 227 sort(); 228 int i; 229 printf("共有%d位学生的信息:\n", n); 230 if (0 != n) 231 { 232 printf("学生学号 学生姓名 年龄 性别 C语言成绩 高等数学 大学英语成绩\n"); 233 printf("--------------------------------------------------------------------\n"); 234 for (i = 0; i < n; i++) 235 { 236 printf("%7s %7s %6d %6c %9.1f %10.1f %10.1f\n", stu[i].code, stu[i].name, stu[i].age, stu[i].sex, stu[i].score[0], stu[i].score[1], stu[i].score[2]); 237 } 238 } 239 system("pause"); 240 } 241 242 /* 保存信息*/ 243 void save() 244 { 245 int i; 246 FILE* fp; 247 char filename[LEN + 1]; 248 printf("请输入要保存该信息的文件名:\n"); /*输入要保存的文件的名字*/ 249 scanf("%s", filename); 250 fp = fopen(filename, "w"); 251 for (i = 0; i < n; i++) 252 { 253 fprintf(fp, "%s%s%d%c%.1f%.1f%.1f\n", stu[i].code, stu[i].name, stu[i].age, stu[i].sex, stu[i].score[0], stu[i].score[1], stu[i].score[2]); 254 } 255 printf("保存成功\n"); 256 fclose(fp); 257 system("pause"); 258 } 259 260 /* 菜单界面*/ 261 void menu(){ 262 int num; 263 printf(" \n\n \n\n"); 264 printf(" ******************************************************\n\n"); 265 printf(" * 学生信息管理系统 *\n \n"); 266 printf(" ******************************************************\n\n"); 267 printf("*********************系统功能菜单************************* \n"); 268 printf(" ---------------------- ---------------------- \n"); 269 printf(" ********************************************* \n"); 270 printf(" ***********按需要选择菜单编号 ********** \n"); 271 printf(" ********************************************* \n"); 272 printf(" * 1.查询学生信息 * * 2.退出系统 * \n"); 273 printf(" ********************************************* \n"); 274 printf(" * 3.增加学生信息 * * 4.显示当前信息 * \n"); 275 printf(" ********************************************* \n"); 276 printf(" * 5.保存当前学生信息* * 6.退出系统 * \n"); 277 printf(" ********************** ********************** \n"); 278 printf(" ********************** \n"); 279 printf(" ---------------------- ---------------------- \n"); 280 printf("请选择菜单编号:"); 281 scanf("%d", &num); 282 switch (num)//此处对菜单进行选择 原理基本类似 283 { 284 case 0:readfile(); break; 285 case 1:seek(); break; 286 case 2: break; 287 case 3:insert(); break; 288 case 4:display(); break; 289 case 5:save(); break; 290 case 6:k = 0; break; 291 default:printf("请在0-6之间选择\n"); 292 } 293 }