本文章是大一時候期末實訓寫的一個學習筆記,有許多代碼都都是參考大佬的代碼來寫的,刪掉了許多功能只有一些基礎功能有許多不足和錯誤之處請大家指正
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 }
