1 /*有于需要额外加载easy-x 图形库 2 所以没有装图形库的Vc6.0编译器不能成功编译该代码 3 可以在可执行程序文件夹内 4 找到已经编译好的exe程序和Data.txt(50000学生信息的输入文件) 5 */ 6 #include<iostream> 7 #include<cstdio> 8 #include<cstdlib> 9 #include<cstring> 10 #include<ctime> 11 #include<vector> 12 #include<graphics.h>//图形库 13 #include<Windows.h> 14 #include<tchar.h> 15 using namespace std; 16 #define MAXN 2010000 //最大值 17 char inName[100];//读取文件的文件名 18 char outName[100];//输出至文件的文件名 19 int num = 0; 20 int maxdeep = 0; 21 char name[30]={0}; 22 typedef int Element; 23 template<class T> 24 struct Node { 25 Node *left_son;//左孩子指针 26 Node *right_son;//右孩子指针 27 T data;//节点储存的信息 28 Node *father;//父亲节点 29 int value;//随机化权值,用于随机数的旋转,保证平衡 30 }; 31 template<class T> 32 class Data_tree {//信息类 基于 平衡树-树堆(Treap)实现 33 public: 34 Data_tree() { 35 init(); 36 } 37 T* Get_head()//平衡树根指针方法 38 { 39 return head; 40 } 41 void Set_head(T *pt)//更改平衡树指针方法 42 { 43 head = pt; 44 } 45 void init() { 46 head = NULL;//根节点置为空节点 47 size = 0; 48 } 49 void left_turn(T *x) {//节点左旋 50 T* y = x->right_son;//y为节点的右孩子 51 if (y->left_son != NULL) { 52 x->right_son = y->left_son;//y的左孩子设置为x的右孩子 53 y->left_son->father = x; 54 } 55 else 56 x->right_son = NULL; 57 y->father = x->father;//y的父亲设置为x的父亲 58 if (y->father == NULL) { 59 Set_head(y); 60 } 61 else { 62 if (y->father->left_son == x)//如果x是他前父亲的左孩子 63 { 64 y->father->left_son = y;//y就成了他父亲的左孩子 65 } 66 else if (y->father->right_son == x)//如果x是他前父亲的右孩子 67 { 68 y->father->right_son = y;//y就成了他父亲的右孩子 69 } 70 } 71 y->left_son = x; 72 x->father = y; 73 } 74 void right_turn(T *y) { 75 T *x = y->left_son;//x是y的左孩子 76 if (x->right_son != NULL) { 77 y->left_son = x->right_son;//把x的右孩子设置为y的左孩子 78 x->right_son->father = y;//y为x的右孩子的父亲 79 } 80 else 81 y->left_son = NULL; 82 x->father = y->father;//将y的父亲设置为x的父亲 83 if (x->father == NULL) {//如果x没有父亲了 84 Set_head(x);//那么它就是根节点 85 } 86 else { 87 if (x->father->left_son == y) { 88 x->father->left_son = x; 89 } 90 else if (x->father->right_son == y) { 91 x->father->right_son = x; 92 } 93 } 94 x->right_son = y; 95 y->father = x; 96 } 97 void insert(T* &pt) {//插入节点pt 98 int index;//树的性质用决定什么树,以及排序的方式 99 T* newp = Get_newNode(); 100 newp->data = pt->data; 101 T* node = Get_head();//获取根节点,以二叉搜索树形式插入 102 size++; 103 if (node == NULL) {//如果是空树 104 Set_head(newp); 105 return; 106 } 107 while (node != NULL) { 108 if (node->data < pt->data) 109 { 110 if (node->right_son == NULL) 111 break; 112 node = node->right_son;//大节点插入右子树 113 } 114 else 115 { 116 if (node->left_son == NULL)//下一个节点为空,跳出循环 117 break; 118 node = node->left_son;//小节点插入左子树 119 } 120 } 121 if (node->data < pt->data) { 122 node->right_son = newp;//插入新节点 123 } 124 else { 125 node->left_son = newp;//插入新节点 126 } 127 newp->father = node; 128 while (node->father != NULL&&node->father->value > node->value) { 129 if (node == node->father->right_son) 130 left_turn(node->father); 131 else if (node == node->father->left_son) 132 right_turn(node->father); 133 } 134 } 135 T* Search(T *pt) { 136 T* node = Get_head();//获取根节点,以二叉搜索树形式查找 137 if (node == NULL) {//如果是空树 138 return 0; 139 } 140 while (node != NULL) { 141 if (node->data == pt->data) { 142 break; 143 } 144 else if (node->data < pt->data) 145 { 146 node = node->right_son;//大节点插入右子树 147 } 148 else 149 { 150 node = node->left_son;//小节点插入左子树 151 } 152 } 153 return node; 154 } 155 bool Erase(T *pt) { 156 T *node = Search(pt); 157 if (node == NULL)//如果没有找到该节点,返回该节点 158 return 0; 159 if (node->father == NULL&&size == 1)//如果是根独苗 160 { 161 Set_head(NULL);//设置为空树 162 size--; 163 return 1; 164 } 165 size--; 166 // cout<<node->right_son<<endl; 167 while (node->left_son != NULL && node->right_son != NULL) { 168 // cout << "???: " << node->data << " " << node->left_son->data << " " << node->right_son->data << endl; 169 if (node->left_son->value<node->right_son->value) { 170 right_turn(node); 171 } 172 else { 173 left_turn(node); 174 } 175 } 176 // cout << "***: " << node << " " << node->left_son << " " << node->right_son << " " << node->father << endl; 177 if (node->left_son != NULL) {//如果还有左孩子 178 if (node->father != NULL) 179 node->left_son->father = node->father; 180 else { 181 Set_head(node->left_son); 182 node->left_son->father = NULL; 183 } 184 if (node->father != NULL) { 185 if (node->father->left_son == node) 186 node->father->left_son = node->left_son; 187 else if (node->father->right_son == node) 188 node->father->right_son = node->left_son; 189 } 190 } 191 else if (node->right_son != NULL) {//如果还有右孩子 192 if (node->father != NULL) { 193 194 node->right_son->father = node->father; 195 } 196 else { 197 Set_head(node->right_son); 198 node->right_son->father = NULL; 199 } 200 if (node->father != NULL) { 201 if (node->father->left_son == node) 202 node->father->left_son = node->right_son; 203 else if (node->father->right_son == node) 204 node->father->right_son = node->right_son; 205 } 206 delete node; 207 } 208 else {//如果没有后代了 209 if (node->father->left_son == node) 210 node->father->left_son = NULL; 211 else if (node->father->right_son == node) 212 node->father->right_son = NULL; 213 delete node; 214 } 215 return 1; 216 } 217 void out(T* pt, int k = 0,FILE *tp=NULL) {//递归前序遍历平衡树 218 if (pt == NULL) return;//空节点不遍历 219 if (pt->left_son != NULL) 220 out(pt->left_son, k,tp); 221 num++; 222 if (k == 1) { 223 printf("%-7d", num); 224 pt->data.out(); 225 putchar('\n'); 226 } 227 else if(k==2){ 228 fprintf(tp,"%-7d", num); 229 pt->data.out(tp); 230 fprintf(tp,"\n"); 231 } 232 if (pt->right_son != NULL) 233 out(pt->right_son, k,tp); 234 } 235 void out2(T* pt, int deep) {//递归前序遍历平衡树 236 if (pt == NULL) return;//空节点不遍历 237 printf("%d\n", pt->value); 238 if (deep>maxdeep) maxdeep = deep; 239 if (pt->left_son != NULL) 240 out(pt->left_son, deep + 1); 241 num++; 242 if (pt->right_son != NULL) 243 out(pt->right_son, deep + 1); 244 } 245 void out3(T *pt, vector<int> *a) { 246 if (pt == NULL) return;//空节点不遍历 247 if (pt->left_son != NULL) 248 out3(pt->left_son, a); 249 a->push_back(pt->data.getnumber()); 250 if (pt->right_son != NULL) 251 out3(pt->right_son, a); 252 } 253 int size;//平衡树的节点个数 254 private: 255 T* head;//平衡树的根节点指针 256 T *Get_newNode() {//获取一个新声明的初始化节点 257 T* pt; 258 pt = new T(); 259 pt->father = NULL;//父亲节点设置为空 260 pt->left_son = NULL;//左右儿子节点置为空 261 pt->right_son = NULL; 262 pt->value = rand();//设置权值为随机数 263 return pt; 264 } 265 }; 266 void get_name(int); 267 struct ScoreData {//学生成绩结构体 268 int score;//分数 269 int number;//学号 270 bool operator<(const struct ScoreData &pt)const { 271 if (this->score != pt.score) 272 return this->score>pt.score; 273 else 274 return this->number<pt.number; 275 } 276 bool operator==(const struct ScoreData &pt)const { 277 return this->number == pt.number; 278 } 279 void out(FILE *pt=NULL)//输出成绩 280 { 281 get_name(number); 282 if(pt==NULL) 283 printf("%-7d %-7d %-7s", number, score,name); 284 else 285 fprintf(pt,"%-7d %-7d %-7s",number,score,name); 286 } 287 }; 288 289 struct NumberData {//学生学号结构体 290 int number;//学号 291 int score;//分数 292 bool operator<(const struct NumberData &pt)const { 293 return number<pt.number; 294 } 295 bool operator==(const struct NumberData &pt)const { 296 return number == pt.number; 297 } 298 int getnumber() { 299 return number; 300 } 301 }; 302 303 struct Student_type { 304 int number;//学号 305 int index;//信息数组下标 306 bool operator<(const Student_type&pt)const { 307 return this->number<pt.number; 308 } 309 bool operator==(const Student_type&pt)const { 310 return this->number == pt.number; 311 } 312 }; 313 struct Student { 314 char name[30]; 315 int number;//该学生的学号 316 char classnumber[20]; 317 char department[20];//该学生的系别编号 318 Student() { 319 name[0] = 0; 320 classnumber[0] = 0; 321 department[0] = 0; 322 } 323 }; 324 325 struct ListNode {//信息链表,节点区别为课程名字或系别或班级名字 326 ListNode *next; 327 Data_tree<Node <ScoreData> > tree_score; 328 Data_tree<Node <NumberData> > tree_number; 329 char s[50]; 330 int lens; 331 int property; 332 }; 333 334 ListNode *Listhead = NULL;//信息链表头 335 336 ListNode* insert_node(char s[], int k = 0) { 337 ListNode *pt = new ListNode();//新生命节点 338 pt->lens = strlen(s); 339 for (int i = 0; i <= pt->lens; i++)/*字符数组s存入新建节点*/ 340 pt->s[i] = s[i]; 341 pt->next = Listhead;//新节点的下一个为头结点 342 pt->property = k;//设置节点优先级 343 Listhead = pt; 344 return Listhead;//返回该节点指针作为返回值 345 } 346 347 348 ListNode* Search(char s[], int k = 0) {//查找链表 349 ListNode *pt = Listhead;//指针指向链表头部 350 int len = strlen(s);//将字符串s的长度存入len 351 while (pt != NULL) {//循环遍历链表 352 if (pt->lens != len)//如果字符串长度不相同,跳过 353 { 354 pt = pt->next; 355 continue; 356 } 357 else {//否则返回逐一检查字符串中每一个字符 358 int ok = 1; 359 for (int i = 0; i<len; i++) 360 if (s[i] != pt->s[i]) {//如果发现不相等字符,就继续 361 ok = 0; 362 break; 363 } 364 if (ok == 1) {//信息吻合,就返回该节点的指针作为返回值 365 return pt; 366 } 367 } 368 pt = pt->next; 369 } 370 pt = insert_node(s, k);//如果没有找到该节点,那么就新建立一个该属性的节点 371 return pt;//返回新建节点的指针值 372 } 373 374 void insert_data(ListNode* pt, int number, int score) {//向链表的平衡树中插入信息 375 Node<ScoreData> *the_data = new Node<ScoreData>();//插入一个成绩信息,用于该科目核对 376 Node<NumberData> *other_data = new Node<NumberData>();//插入一个学号信息,是否有该学生 377 ScoreData sdata; 378 NumberData odata; 379 odata.number = number;//设置该节点编号 380 other_data->data = odata; 381 other_data = pt->tree_number.Search(other_data); 382 if (other_data != NULL) {//如果该节点非空 383 sdata.number = number;//设置学号 384 sdata.score = other_data->data.score; 385 the_data->data = sdata; 386 pt->tree_score.Erase(the_data);//尝试删除该信息原来的点,以达到覆盖效果 387 } 388 sdata.number = number;//设置节点的学号 389 sdata.score = score;//设置节点的分数 390 the_data->data = sdata; 391 other_data = new Node<NumberData>(); 392 pt->tree_score.insert(the_data);//插入该节点 393 odata.score = score;//设置节点的分数 394 odata.number = number;//设置节点的学号 395 other_data->data = odata; 396 pt->tree_number.Erase(other_data);//尝试删除该信息原来的点(如果有的话),以达到覆盖效果 397 pt->tree_number.insert(other_data);//插入该节点 398 } 399 400 void erase_data(ListNode* pt, int number) {//向链表的平衡树中删除信息 401 Node<ScoreData> *the_data = new Node<ScoreData>();//插入一个成绩信息,用于该科目核对 402 ScoreData sdata; 403 sdata.number = number;//设置节点学号 404 the_data->data = sdata; 405 pt->tree_score.Erase(the_data);//尝试删除该信息原来的点(如果有的话), 406 Node<NumberData> *other_data = new Node<NumberData>();//建立一个学号信息 407 NumberData odata; 408 odata.number = number; 409 other_data->data = odata; 410 pt->tree_number.Erase(other_data);//尝试删除该信息原来的点(如果有的话),以达到覆盖效果 411 } 412 413 int getsumscore(int number, int k = 0) {//当k=1时输出该学生各科目信息 414 int sum = 0;//初始化总分数变量 415 ListNode* pt = Listhead;//指针指向链表头部 416 Node<NumberData> *other_data = new Node<NumberData>(); 417 NumberData odata; 418 odata.number = number;//设置学号 419 other_data->data = odata; 420 Node<NumberData> *search_data; 421 while (pt != NULL) {//遍历链表 422 if (pt->property != 0) {//如果不是课程节点 423 pt = pt->next;//链表指针指向下一个 424 continue; 425 } 426 search_data = pt->tree_number.Search(other_data);//查找是否能找到有该学号的人 427 428 if (search_data == NULL) {//如果节点为空,那么就跳过 429 pt = pt->next;//链表指针指向下一个 430 continue; 431 } 432 sum += search_data->data.score;//加入成绩至总分 433 if (k != 0)//如果不为0就输出 434 printf("其%s科目的成绩为: %d\n", pt->s, search_data->data.score); 435 pt = pt->next;//链表指针指向下一个 436 } 437 if (k != 0) 438 printf("其总分为: %d\n", sum); 439 return sum; 440 } 441 442 int studentnum = 0;//学生编号表 443 Student studentlist[MAXN];//学生信息表 444 Data_tree<Node <Student_type> > studenttree; 445 int student_insert(int number) {//新插入一个学号的学生 446 //Student_type pt = new Student_type(); 447 Node<Student_type> *pt = new Node<Student_type>(); 448 pt->data.number = number; 449 pt->data.index = studentnum; 450 studentlist[studentnum].number = number; 451 studenttree.insert(pt); 452 return studentnum++;//返回当前编号 453 } 454 455 456 int get_student_index(int number)//获取该学号在学生数组里的下标 457 { 458 Node<Student_type> *pt = new Node<Student_type>(); 459 pt->data.number = number; 460 pt = studenttree.Search(pt); 461 if (pt == NULL) 462 return -1;//失败返回-1 463 else 464 return pt->data.index;//成功返回编号 465 } 466 467 void set_student_name(int number, char s[])//设置该学号学生的名字 468 { 469 int index = get_student_index(number); 470 if (index<0)//若没有该学生信息 471 index = student_insert(number);//插入该学生信息 472 int size = strlen(s); 473 for (int i = 0; i <= size; i++) 474 studentlist[index].name[i] = s[i];//设置学生的名字 475 return; 476 } 477 478 void set_student_classnumber(int number, char s[]) { 479 int index = get_student_index(number); 480 if (index<0)//若没有该学生信息 481 index = student_insert(number);//插入该学生信息 482 int lens = strlen(studentlist[index].classnumber); 483 if (lens > 0)//如果发现有原来班级的信息 484 { 485 ListNode* pt; 486 pt = Search(studentlist[index].classnumber, 1);//找到原来班级的链表节点 487 erase_data(pt, number);//从原来班级删除该学生 488 } 489 int size = strlen(s); 490 for (int i = 0; i <= size; i++) 491 studentlist[index].classnumber[i] = s[i];//设置学生的班级名字 492 return; 493 } 494 495 void get_name(int number) { 496 int index = get_student_index(number); 497 if (index<0)//若没有该学生信息 498 { 499 name[0]='N',name[1]='o',name[2]='t',name[3]=' ',name[4]='s'; 500 name[5]='e',name[5]='t',name[5]=' ',name[6]='n';name[7]='a'; 501 name[8]='m',name[9]='e',name[10]=0; 502 return;//设置没有名字 503 } 504 int lens = strlen(studentlist[index].name); 505 for(int i=0;i<=lens;i++) 506 name[i]=studentlist[index].name[i]; 507 return; 508 } 509 510 void set_student_department(int number, char s[]) { 511 int index = get_student_index(number); 512 if (index<0)//若没有该学生信息 513 index = student_insert(number);//插入该学生信息 514 int lens = strlen(studentlist[index].department); 515 if (lens > 0)//如果发现有原来系别的信息 516 { 517 ListNode* pt; 518 pt = Search(studentlist[index].department, 1);//找到原来系别的链表节点 519 erase_data(pt, number);//从原来系别删除该学生 520 } 521 int size = strlen(s); 522 for (int i = 0; i <= size; i++) 523 studentlist[index].department[i] = s[i];//设置学生的系别名字 524 return; 525 } 526 527 528 void Screen_clear() {//清空屏幕 529 system("cls"); 530 } 531 532 int Get_score(char s[], int number) {//获取s课程number学号的成绩 533 ListNode *pt = Search(s); 534 Node<NumberData> *other_data = new Node<NumberData>(); 535 NumberData odata; 536 odata.number = number; 537 other_data->data = odata; 538 other_data = pt->tree_number.Search(other_data); 539 if (other_data == NULL)//没有找到该学生 540 return 0; 541 else 542 return other_data->data.score; 543 } 544 545 int Get_score(ListNode *pt, int number) {//获取课程指针pt内number学号学生的成绩 546 if (pt == NULL) 547 return 0; 548 Node<NumberData> *other_data = new Node<NumberData>(); 549 NumberData odata; 550 odata.number = number; 551 other_data->data = odata; 552 other_data = pt->tree_number.Search(other_data); 553 if (other_data == NULL)//没有找到该学生 554 return 0; 555 else 556 return other_data->data.score; 557 } 558 void Input_System() {//录入系统 559 Screen_clear();//清屏 560 printf("欢迎您进入学生成绩录入系统\n"); 561 printf("本系统采用命令式信息采集方案\n"); 562 printf("如果输入之前已设置的信息会覆盖即发生修改\n"); 563 printf("命令菜单:\n"); 564 printf("命令\t\t\t\t功能\n"); 565 printf("%-22s\t\t%s\n", "In data.txt", "读取data.txt全部内容直至文件尾(可自定义文件名)"); 566 printf("%-22s\t\t%s\n", "CloseFile", "关闭文件输入方式(需要在文件中输出)"); 567 printf("%-22s\t%s\n", "Set Name 1608024101 王XX", "1608024101的学生的名字为王xx"); 568 printf("%-22s\t%s\n", "Set Class 1608024101 16080241", "1608024101的学生的班级为16080241"); 569 printf("%-22s\t%s\n", "Set Department 1608024101 8院", "1608024101的学生的系别为8院"); 570 printf("%-22s\t%s\n", "Set Score 算法 1608024101 0", "将学号为1608024101的算法成绩设置为0分"); 571 printf("%-25s\t%s\n", "Exit", "退出当前子系统"); 572 printf("现在请您输入相应的指令:\n"); 573 FILE *in;//文件读入指针 574 int wj = 0; 575 int start = 0; 576 while (1) { 577 char s[300]; 578 if (wj == 0) { 579 scanf("%s", s);//获命令 580 int len = strlen(s); 581 if (len <= 0) { 582 printf("语法错误\n"); 583 fflush(stdin);//清空输入缓冲区 584 } 585 if (s[0] == 'I') { 586 scanf("%s", inName); 587 in = fopen(inName, "r"); 588 if (in == 0) { 589 printf("打开文件失败,请检查\n"); 590 continue; 591 } 592 else { 593 printf("打开文件成功\n"); 594 wj = 1; 595 start = clock(); 596 continue; 597 } 598 } 599 else if (s[0] == 'C') { 600 wj = 0; 601 in = NULL; 602 int finish = clock();//获取当前时钟 603 printf("读取,并且创建平衡树成功\n共耗时%.6f秒\n", (double)(finish - start) / CLOCKS_PER_SEC); 604 printf("成功将输入源转至键盘\n"); 605 continue; 606 } 607 else if (s[0] == 'S') { 608 scanf("%s", s); 609 if (s[0] == 'N') { 610 char name[300]; 611 int number; 612 scanf("%d", &number); 613 scanf("%s", name); 614 set_student_name(number, name); 615 printf("设置名字成功\n"); 616 } 617 else if (s[0] == 'C') { 618 char classes[300]; 619 int number; 620 scanf("%d", &number); 621 scanf("%s", classes); 622 set_student_classnumber(number, classes); 623 ListNode *pt; 624 pt = Search(classes, 1); 625 insert_data(pt, number, 1); 626 printf("设置班级成功\n"); 627 } 628 else if (s[0] == 'D') { 629 char department[300]; 630 int number; 631 scanf("%d", &number); 632 scanf("%s", department); 633 set_student_department(number, department); 634 ListNode *pt; 635 pt = Search(department, 1); 636 insert_data(pt, number, 1); 637 printf("设置系别成功\n"); 638 } 639 else if (s[0] == 'S') { 640 int number; 641 char coursename[30]; 642 int score; 643 scanf("%s", coursename); 644 scanf("%d%d", &number, &score); 645 int index = get_student_index(number); 646 if (index<0)//若没有该学生信息 647 index = student_insert(number);//插入该学生信息 648 ListNode *pt; 649 pt = Search(coursename); 650 insert_data(pt, number, score); 651 printf("设置成绩成功\n"); 652 } 653 else { 654 printf("语法错误\n"); 655 fflush(stdin);//清空输入缓冲区 656 } 657 } 658 else if (s[0] == 'E') { 659 printf("即将在2秒后退出\n"); 660 Sleep(2000); 661 return; 662 } 663 else { 664 printf("语法错误\n"); 665 fflush(stdin);//清空输入缓冲区 666 } 667 } 668 else { 669 if(fscanf(in, "%s", s)==EOF){ 670 s[0]='C'; 671 s[1]=0;//没有文件,设置结束 672 };//获命令 673 int len = strlen(s); 674 if (len <= 0) { 675 } 676 else if (s[0] == 'C') { 677 wj = 0; 678 in = NULL; 679 int finish = clock();//获取当前时钟 680 printf("读取,并且创建平衡树成功\n共耗时%.6f秒\n", (double)(finish - start) / CLOCKS_PER_SEC); 681 printf("成功将输入源转至键盘\n"); 682 continue; 683 } 684 else if (s[0] == 'S') { 685 fscanf(in, "%s", s); 686 if (s[0] == 'N') { 687 char name[300]; 688 int number; 689 fscanf(in, "%d", &number); 690 fscanf(in, "%s", name); 691 set_student_name(number, name); 692 } 693 else if (s[0] == 'C') { 694 char classes[300]; 695 int number; 696 fscanf(in, "%d", &number); 697 fscanf(in, "%s", classes); 698 set_student_classnumber(number, classes); 699 ListNode *pt; 700 pt = Search(classes, 1); 701 insert_data(pt, number, 1); 702 } 703 else if (s[0] == 'D') { 704 char department[300]; 705 int number; 706 fscanf(in, "%d", &number); 707 fscanf(in, "%s", department); 708 set_student_department(number, department); 709 ListNode *pt; 710 pt = Search(department, 1); 711 insert_data(pt, number, 1); 712 } 713 else if (s[0] == 'S') { 714 int number; 715 char coursename[30]; 716 int score; 717 fscanf(in, "%s", coursename); 718 fscanf(in, "%d%d", &number, &score); 719 int index = get_student_index(number); 720 if (index<0)//若没有该学生信息 721 index = student_insert(number);//插入该学生信息 722 ListNode *pt; 723 pt = Search(coursename); 724 insert_data(pt, number, score); 725 } 726 } 727 } 728 } 729 } 730 731 vector<int> num_vector; 732 ScoreData* Score_vector; 733 734 void Output_System() {//输出系统 735 Screen_clear();//清屏 736 printf("欢迎您进入信息输出系统\n"); 737 printf("本系统采用命令式交互方案\n"); 738 printf("命令菜单:\n"); 739 printf("命令\t\t\t\t\t功能\n"); 740 printf("%-22s\t\t%s\n", "Query Number 1608024101", "输出1608024101的各科目成绩"); 741 printf("%-22s\t\t%s\n", "Query Data 1608024101", "输出1608024101的信息"); 742 printf("%-22s\t\t%s\n", "Query Course 数学分析", "输出数学分析科目的所有的成绩"); 743 printf("%-22s\t\t%s\n", "Query Department 8院", "输出8院的所有同学的学号"); 744 printf("%-22s\t\t%s\n", "Query Class 16080241", "输出16080241班的所有同学的学号"); 745 printf("%-25s\t\t%s\n", "Exit", "退出当前子系统"); 746 printf("现在请您输入相应的指令:\n"); 747 while (1) { 748 char s[300]; 749 num = 0; 750 scanf("%s", s);//获命令 751 int len = strlen(s); 752 if (len <= 1) { 753 printf("语法错误\n"); 754 fflush(stdin);//清空输入缓冲区 755 continue; 756 } 757 if (s[0] == 'Q') { 758 scanf("%s", s); 759 if (strlen(s) < 3) { 760 printf("语法错误\n"); 761 fflush(stdin);//清空输入缓冲区 762 continue; 763 } 764 if (s[0] == 'N'&&s[1] == 'u') { 765 char name[300]; 766 int number; 767 scanf("%d", &number); 768 getsumscore(number, 1); 769 printf("查找该学生成绩成功\n"); 770 } 771 else if (s[0] == 'D'&&s[1] == 'a') { 772 char name[300]; 773 int number; 774 scanf("%d", &number); 775 int index = get_student_index(number); 776 if (index < 0)//没有该生信息 777 { 778 printf("对不起,并没有找到该学号的学生\n"); 779 continue; 780 } 781 else if (index >= 0) { 782 printf("学号:%d\n", number); 783 if (strlen(studentlist[index].name) > 0) 784 printf("姓名:%s\n", studentlist[index].name); 785 else 786 printf("姓名:尚未定义\n"); 787 if (strlen(studentlist[index].classnumber) > 0) 788 printf("班级:%s\n", studentlist[index].classnumber); 789 else 790 printf("班级:尚未定义\n"); 791 if (strlen(studentlist[index].department) > 0) 792 printf("系别:%s\n", studentlist[index].department); 793 else 794 printf("系别:尚未定义\n"); 795 } 796 printf("查找该学生信息成功\n"); 797 continue; 798 } 799 else if (s[0] == 'C'&&s[1] == 'o') { 800 char classes[300]; 801 scanf("%s", classes); 802 ListNode* pt; 803 pt = Search(classes); 804 printf("%7s %7s %7s %7s\n", "名次", "学号", "成绩","姓名"); 805 pt->tree_score.out(pt->tree_score.Get_head(), 1); 806 } 807 else if (s[0] == 'D') { 808 char department[300]; 809 scanf("%s", department); 810 ListNode* pt; 811 pt = Search(department); 812 printf("%7s %7s\n", "序号", "学号"); 813 num_vector.clear(); 814 pt->tree_number.out3(pt->tree_number.Get_head(), &num_vector); 815 int i; 816 for (i = 0; i < num_vector.size(); i++) { 817 printf("%-7d%-7d\n", i + 1, num_vector[i]); 818 } 819 } 820 else if (s[0] == 'C'&&s[1] == 'l') { 821 char classes[300]; 822 scanf("%s", classes); 823 ListNode* pt; 824 pt = Search(classes); 825 printf("%7s %7s\n", "序号", "学号"); 826 num_vector.clear(); 827 pt->tree_number.out3(pt->tree_number.Get_head(), &num_vector); 828 int i; 829 for (i = 0; i < num_vector.size(); i++) { 830 printf("%7d %7d\n", i + 1, num_vector[i]); 831 } 832 } 833 else { 834 printf("语法错误\n"); 835 fflush(stdin);//清空输入缓冲区 836 } 837 } 838 else if (s[0] == 'E') { 839 printf("即将在2秒后退出\n"); 840 Sleep(2000); 841 return; 842 } 843 else { 844 printf("语法错误\n"); 845 fflush(stdin);//清空输入缓冲区 846 } 847 } 848 } 849 850 void swap(ScoreData *p, ScoreData *q) { //交换两个变量的值 851 ScoreData t = *q; 852 *q = *p; *p = t; 853 } 854 855 void Quicksort(ScoreData a[], int l, int r) {//快速排序 856 if (l >= r) return;//区间内小于等于1个元素的时候,不用排序,直接返回 857 int t = rand() % (r - l + 1) + l; //t为基准值位置,这里采用随机选取 858 swap(&a[l], &a[t]); 859 int i = l, j = r; 860 ScoreData mid = a[l]; 861 while (i<j) { 862 while (i < j&&mid < a[j]) j--; //将比基准值小的元素放在基准值左边 863 a[i] = a[j]; 864 while (i < j && !(mid < a[i])) i++; //将比基准值大的元素放在基准值右边 865 a[j] = a[i]; 866 } 867 a[i] = mid;//基准值放在中间 868 Quicksort(a, l, i - 1);//递归排序基准值左边 869 Quicksort(a, i + 1, r);//递归排序基准值右边 870 } 871 872 int pass_score = 60, good_score = 90;//及格线,优秀线 873 void analy(ScoreData a[], int n) { 874 int passnum = 0, goodnum = 0;//及格人数,优秀人数 875 for (int i = 0; i < n; i++) { 876 if (a[i].score >= pass_score) 877 passnum++; 878 if (a[i].score >= good_score) 879 goodnum++; 880 } 881 printf("总人数: %d\n", n); 882 printf("及格人数: %d\n", passnum); 883 printf("及格率: %.2f\n", (double)passnum / n); 884 printf("优秀人数: %d\n", goodnum); 885 printf("优秀率: %.2f\n", (double)goodnum / n); 886 } 887 888 void analy2(ScoreData a[], int n) { 889 int minn = 0x3f3f3f3f, maxn = 0;//及格人数,优秀人数 890 int ans = 0; 891 for (int i = 0; i < n; i++) { 892 if (a[i].score > maxn) 893 maxn = a[i].score; 894 if (a[i].score < minn) 895 minn = a[i].score; 896 ans += a[i].score; 897 } 898 printf("总人数: %d\n", n); 899 printf("最高分数: %d\n", maxn); 900 printf("最低分数: %d\n", minn); 901 printf("平均成绩: %.2f\n", (double)ans / n); 902 } 903 904 void Analyze_System() { 905 Screen_clear();//清除屏幕 906 printf("欢迎您进入成绩分析系统\n"); 907 printf("本系统采用命令式交互方案\n"); 908 printf("命令菜单:\n"); 909 printf("命令\t\t\t\t\t功能\n"); 910 printf("%-22s\t\t%s\n", "Analyze Class 16080241 数学分析", "输出16080241班的数学分析的成绩分析"); 911 printf("%-22s\t%s\n", "Analyze Department 数学系 数学分析", "输出数学系班的数学分析的成绩分析"); 912 printf("%-22s\t\t\t%s\n", "Set Goodline 95", "设置优秀线95 默认是90分"); 913 printf("%-22s\t\t\t%s\n", "Set Passline 50", "设置及格线50 默认是60分"); 914 printf("%-25s\t\t%s\n", "Exit", "退出当前子系统"); 915 printf("现在请您输入相应的指令:\n"); 916 while (1) { 917 char s[300]; 918 scanf("%s", s); 919 if (s[0] == 'A') { 920 scanf("%s", s); 921 if (strlen(s) < 1) { 922 printf("语法错误\n"); 923 continue; 924 } 925 else if (s[0] == 'C') { 926 char classes[300]; 927 scanf("%s", classes); 928 ListNode* pt; 929 pt = Search(classes); 930 num_vector.clear(); 931 pt->tree_number.out3(pt->tree_number.Get_head(), &num_vector); 932 if (num_vector.size() == 0) { 933 printf("该列表没有成员\n"); 934 continue; 935 } 936 int i; 937 char name[300]; 938 scanf("%s", name); 939 pt = Search(name, 1);//获取该课程指针 940 Score_vector = new ScoreData[num_vector.size()];//创立一个该班人数大小的线性表 941 for (i = 0; i < num_vector.size(); i++) { 942 Score_vector[i].number = num_vector[i];//存储学号 943 Score_vector[i].score = Get_score(pt, Score_vector[i].number); 944 } 945 analy(Score_vector, num_vector.size()); 946 } 947 else if (s[0] == 'D') { 948 char department[300]; 949 scanf("%s", department); 950 ListNode* pt; 951 pt = Search(department); 952 //printf("%7s %7s\n", "序号", "学号"); 953 num_vector.clear(); 954 pt->tree_number.out3(pt->tree_number.Get_head(), &num_vector); 955 char name[300]; 956 scanf("%s", name); 957 if (num_vector.size() == 0) { 958 printf("该列表没有成员\n"); 959 continue; 960 } 961 pt = Search(name, 1);//获取该课程指针 962 int i; 963 Score_vector = new ScoreData[num_vector.size()];//创立一个该系人数大小的线性表 964 for (i = 0; i < num_vector.size(); i++) { 965 Score_vector[i].number = num_vector[i];//存储学号 966 Score_vector[i].score = Get_score(pt, Score_vector[i].number); 967 } 968 analy(Score_vector, num_vector.size()); 969 } 970 else { 971 printf("语法错误\n"); 972 continue; 973 } 974 } 975 else if (s[0] == 'S') { 976 int d; 977 scanf("%s", s); 978 scanf("%d", &d); 979 if (s[0] == 'G') { 980 good_score = d;//设置优秀线 981 printf("设置成功\n"); 982 } 983 else if (s[0] == 'P') { 984 pass_score = d;//设置及格线 985 printf("设置成功\n"); 986 } 987 } 988 else if (s[0] == 'E') { 989 return; 990 } 991 } 992 } 993 994 void Course_System() { 995 Screen_clear();//清除屏幕 996 printf("欢迎您进入课程成绩分析系统\n"); 997 printf("请输出操作指令:\n"); 998 printf("1.分析课程\n"); 999 printf("2.退出\n"); 1000 while (1) { 1001 int c = getchar(); 1002 while (!(c > '0'&&c <= '2')) { 1003 c = getchar(); 1004 continue; 1005 } 1006 if (c == '1') { 1007 printf("请输入分析的课程名字:\n"); 1008 char name[300]; 1009 scanf("%s", name); 1010 ListNode* pt; 1011 pt = Search(name); 1012 num_vector.clear(); 1013 pt->tree_number.out3(pt->tree_number.Get_head(), &num_vector); 1014 if (num_vector.size() == 0) { 1015 printf("该列表没有成员\n"); 1016 continue; 1017 } 1018 int i; 1019 Score_vector = new ScoreData[num_vector.size()];//创立一个该课程人数大小的线性表 1020 for (i = 0; i < num_vector.size(); i++) { 1021 Score_vector[i].number = num_vector[i];//存储学号 1022 Score_vector[i].score = Get_score(pt, Score_vector[i].number); 1023 } 1024 analy2(Score_vector, num_vector.size()); 1025 } 1026 else if (c == '2') 1027 return; 1028 } 1029 } 1030 1031 void Rank_System() {//排名系统 1032 Screen_clear();//清除屏幕 1033 printf("欢迎您进入成绩排名系统\n"); 1034 printf("本系统采用命令式交互方案\n"); 1035 printf("命令菜单:\n"); 1036 printf("命令\t\t\t\t\t功能\n"); 1037 printf("%-22s\t\t\t%s\n", "Out to data.txt", "将排名输出至 data.txt 可以自定义文件名"); 1038 printf("%-22s\t\t\t%s\n", "Out Recover", "将排名重新输出至屏幕"); 1039 printf("%-22s\t\t%s\n", "Rank Class 16080241 数学分析", "输出16080241班的数学分析的成绩排名"); 1040 printf("%-22s\t\t%s\n", "Rank Department 数学系 数学分析", "输出数学系的数学分析的成绩排名"); 1041 printf("%-22s\t\t\t%s\n", "Rank AllClass 16080241", "输出16080241班的数学分析的成绩排名"); 1042 printf("%-22s\t\t%s\n", "Rank AllDepartment 数学系", "输出数学系的总成绩的成绩排名"); 1043 printf("%-25s\t\t%s\n", "Exit", "退出当前子系统"); 1044 printf("现在请您输入相应的指令:\n"); 1045 int i; 1046 int wj = 0;//是否进行文件输出 1047 FILE* filepoint; 1048 while (1) { 1049 char s[300]; 1050 scanf("%s", s); 1051 if (s[0] == 'O') { 1052 scanf("%s", outName); 1053 if (outName[0] == 't') { 1054 scanf("%s", outName); 1055 filepoint = fopen(outName, "w+"); 1056 if (filepoint == NULL) { 1057 printf("输出转向文件失败!\n"); 1058 continue; 1059 } 1060 else { 1061 printf("输出转向文件成功\n"); 1062 wj = 1; 1063 continue; 1064 } 1065 } 1066 else { 1067 if (outName[0] == 'R' || outName[0] == 'r') { 1068 fclose(filepoint); 1069 filepoint = NULL; 1070 wj = 0; 1071 printf("输出转至屏幕成功\n"); 1072 continue; 1073 } 1074 } 1075 } 1076 else if (s[0] == 'R') { 1077 scanf("%s", s); 1078 if (s[0] == 'C') { 1079 char classes[300]; 1080 scanf("%s", classes); 1081 ListNode* pt; 1082 pt = Search(classes); 1083 num_vector.clear(); 1084 pt->tree_number.out3(pt->tree_number.Get_head(), &num_vector); 1085 scanf("%s", classes); 1086 if (num_vector.size() == 0) { 1087 printf("该列表没有成员\n"); 1088 continue; 1089 } 1090 pt = Search(classes, 1);//获取该课程指针 1091 Score_vector = new ScoreData[num_vector.size()];//创立一个该班人数大小的线性表 1092 for (i = 0; i < num_vector.size(); i++) { 1093 //printf("%7d %7d\n", i + 1, num_vector[i]); 1094 Score_vector[i].number = num_vector[i];//存储学号 1095 Score_vector[i].score = Get_score(pt, Score_vector[i].number); 1096 } 1097 Quicksort(Score_vector, 0, num_vector.size() - 1); 1098 if (wj == 0) 1099 printf("%7s %7s %7s %7s\n", "排名", "学号", "分数","名字"); 1100 else 1101 fprintf(filepoint, "%7s %7s %7s %7s\n", "排名", "学号", "分数","名字"); 1102 int i; 1103 int start = clock(); 1104 for (i = 0; i <= num_vector.size() - 1; i++) { 1105 get_name(Score_vector[i].number); 1106 if (wj == 0) 1107 printf("%7d %7d %7d %7s\n", i + 1, Score_vector[i].number, Score_vector[i].score,name); 1108 else 1109 fprintf(filepoint, "%7d %7d %7d %7s\n", i + 1, Score_vector[i].number, Score_vector[i].score,name); 1110 } 1111 int finish = clock(); 1112 if (wj == 1) { 1113 printf("输出至文件成功,所用时间: %.6f 秒\n", (double)(finish - start) / CLOCKS_PER_SEC); 1114 } 1115 } 1116 else if (s[0] == 'D') { 1117 char department[300]; 1118 scanf("%s", department); 1119 ListNode* pt; 1120 pt = Search(department); 1121 num_vector.clear(); 1122 pt->tree_number.out3(pt->tree_number.Get_head(), &num_vector); 1123 scanf("%s", department); 1124 if (num_vector.size() == 0) { 1125 printf("该列表没有成员\n"); 1126 continue; 1127 } 1128 pt = Search(department, 1);//获取该课程指针 1129 Score_vector = new ScoreData[num_vector.size()];//创立一个该系别人数大小的线性表 1130 for (i = 0; i < num_vector.size(); i++) { 1131 Score_vector[i].number = num_vector[i];//存储学号 1132 Score_vector[i].score = Get_score(pt, Score_vector[i].number); 1133 } 1134 Quicksort(Score_vector, 0, num_vector.size() - 1); 1135 if (wj == 0) 1136 printf("%7s %7s %7s %7s\n", "排名", "学号", "分数","名字"); 1137 else 1138 fprintf(filepoint, "%7s %7s %7s %7s\n", "排名", "学号", "分数","名字"); 1139 int start = clock(); 1140 for (i = 0; i <= num_vector.size() - 1; i++) { 1141 get_name(Score_vector[i].number); 1142 if (wj == 0) 1143 printf("%7d %7d %7d %7s\n", i + 1, Score_vector[i].number, Score_vector[i].score,name); 1144 else 1145 fprintf(filepoint, "%7d %7d %7d %7s\n", i + 1, Score_vector[i].number, Score_vector[i].score,name); 1146 } 1147 int finish = clock(); 1148 if (wj == 1) { 1149 printf("输出至文件成功,所用时间: %.6f 秒\n", (double)(finish - start) / CLOCKS_PER_SEC); 1150 } 1151 } 1152 else if (s[0] == 'A'&&strlen(s) > 4 && s[3] == 'C') { 1153 char classes[300]; 1154 scanf("%s", classes); 1155 ListNode* pt; 1156 pt = Search(classes); 1157 num_vector.clear(); 1158 pt->tree_number.out3(pt->tree_number.Get_head(), &num_vector); 1159 if (num_vector.size() == 0) { 1160 printf("该列表没有成员\n"); 1161 continue; 1162 } 1163 Score_vector = new ScoreData[num_vector.size()];//创立一个该班人数大小的线性表 1164 for (i = 0; i < num_vector.size(); i++) { 1165 Score_vector[i].number = num_vector[i];//存储学号 1166 Score_vector[i].score = getsumscore(Score_vector[i].number); 1167 } 1168 Quicksort(Score_vector, 0, num_vector.size() - 1); 1169 if (wj == 0) 1170 printf("%7s %7s %7s %7s\n", "排名", "学号", "分数","名字"); 1171 else 1172 fprintf(filepoint, "%7s %7s %7s %7s\n", "排名", "学号", "分数","名字"); 1173 int i; 1174 int start = clock(); 1175 for (i = 0; i <= num_vector.size() - 1; i++) { 1176 get_name(Score_vector[i].number); 1177 if (wj == 0) 1178 printf("%7d %7d %7d %7s\n", i + 1, Score_vector[i].number, Score_vector[i].score,name); 1179 else 1180 fprintf(filepoint, "%7d %7d %7d %7s\n", i + 1, Score_vector[i].number, Score_vector[i].score,name); 1181 } 1182 int finish = clock(); 1183 if (wj == 1) { 1184 printf("输出至文件成功,所用时间: %.6f 秒\n", (double)(finish - start) / CLOCKS_PER_SEC); 1185 } 1186 } 1187 else if (s[0] == 'A'&&strlen(s) > 4 && s[3] == 'D') { 1188 char department[300]; 1189 scanf("%s", department); 1190 ListNode* pt; 1191 pt = Search(department); 1192 num_vector.clear(); 1193 pt->tree_number.out3(pt->tree_number.Get_head(), &num_vector); 1194 int i; 1195 if (num_vector.size() == 0) { 1196 printf("该列表没有成员\n"); 1197 continue; 1198 } 1199 Score_vector = new ScoreData[num_vector.size()];//创立一个该系别人数大小的线性表 1200 for (i = 0; i < num_vector.size(); i++) { 1201 Score_vector[i].number = num_vector[i];//存储学号 1202 Score_vector[i].score = getsumscore(Score_vector[i].number); 1203 } 1204 Quicksort(Score_vector, 0, num_vector.size() - 1); 1205 if (wj == 0) 1206 printf("%7s %7s %7s %7s\n", "排名", "学号", "分数","名字"); 1207 else 1208 fprintf(filepoint, "%7s %7s %7s %7s\n", "排名", "学号", "分数","名字"); 1209 int start = clock(); 1210 for (i = 0; i <= num_vector.size() - 1; i++) { 1211 get_name(Score_vector[i].number); 1212 if (wj == 0) 1213 printf("%7d %7d %7d %7s\n", i + 1, Score_vector[i].number, Score_vector[i].score,name); 1214 else 1215 fprintf(filepoint, "%7d %7d %7d %7s\n", i + 1, Score_vector[i].number, Score_vector[i].score,name); 1216 } 1217 int finish = clock(); 1218 if (wj == 1) { 1219 printf("输出至文件成功,所用时间: %.6f 秒\n", (double)(finish - start) / CLOCKS_PER_SEC); 1220 } 1221 } 1222 else { 1223 if (wj == 0) 1224 printf("语法错误\n"); 1225 continue; 1226 } 1227 } 1228 else if (s[0] == 'E') { 1229 return; 1230 } 1231 } 1232 } 1233 const int X = 800, Y = 600;//画面宽度与高度 1234 1235 int getmouse() { 1236 MOUSEMSG mouse_message;//鼠标消息变量 1237 while (1) { 1238 if (MouseHit()) {//如果有鼠标消息,进入if 1239 mouse_message = GetMouseMsg();//获取当前的鼠标消息 1240 if (mouse_message.uMsg == WM_LBUTTONDOWN)//如果鼠标左键按下 1241 { 1242 int x = mouse_message.x; 1243 int y = mouse_message.y;//获取鼠标当前所在的坐标 1244 /*检查鼠标位置*/ 1245 if (x >= 100 && y >= 20 && x <= 300 && y <= 140) 1246 return 1;//退出鼠标检测函数,进入下一项 1247 else if (x >= 500 && y >= 20 && x <= 700 && y <= 140) 1248 return 2;//退出鼠标检测函数,进入下一项 1249 else if (x >= 100 && y >= 250 && x <= 300 && y <= 370) 1250 return 3;//退出鼠标检测函数,进入下一项 1251 else if (x >= 500 && y >= 250 && x <= 700 && y <= 370) 1252 return 4; 1253 } 1254 FlushMouseMsgBuffer();//清空鼠标消息,以避免消息冲突 1255 } 1256 } 1257 } 1258 1259 void Message(char *s1, char *s2) {//提示框 1260 HWND hwnd = GetHWnd();//获取窗口句柄 1261 MessageBox(hwnd, s1, s2, 0);//输出相关内容 1262 } 1263 char s[1000]; 1264 void openfile()//图形化文件读取 1265 { 1266 const int Max_PATH = 100; 1267 TCHAR szBuffer[Max_PATH] = { 0 }; //保存文件名 1268 HWND m_hWnd = GetHWnd();//获取窗口句柄 1269 OPENFILENAME ofn = { 0 }; 1270 ofn.lStructSize = sizeof(ofn); 1271 ofn.hwndOwner = m_hWnd; 1272 ofn.lpstrFilter = _T("TxT文件(*.txt)*.txt所有文件(*.*)*.*");//要选择的文件后缀 1273 ofn.lpstrInitialDir = _T("C:\\Users\\Administrator\\Desktop\\");//默认的文件路径 1274 ofn.lpstrFile = szBuffer;//存放文件的缓冲区 1275 ofn.nMaxFile = sizeof(szBuffer) / sizeof(*szBuffer); 1276 ofn.nFilterIndex = 0; 1277 ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER;//标志如果是多选要加上OFN_ALLOWMULTISELECT 1278 BOOL bSel = GetOpenFileName(&ofn); 1279 if (bSel == false) { 1280 Message("请检查文件输入", "请检查文件输入"); 1281 return; 1282 } 1283 FILE* in = NULL; 1284 in = fopen(szBuffer, "r");//只读方式打开文件 1285 if (in == NULL) {//文件打开失败 1286 Message("请检查文件是否存在", "请检查文件是否存在"); 1287 return; 1288 } 1289 while (1) {//读取文件 1290 if(fscanf(in, "%s", s)==EOF) 1291 s[0]='C',s[1]=0; 1292 int len = strlen(s); 1293 if (len <= 0) { 1294 } 1295 else if (s[0] == 'C') { 1296 fclose(in); 1297 in = NULL; 1298 int finish = clock();//获取当前时钟 1299 Message("读取成功", "成功"); 1300 return; 1301 } 1302 else if (s[0] == 'S') { 1303 fscanf(in, "%s", s); 1304 if (s[0] == 'N') { 1305 char name[300]; 1306 int number; 1307 fscanf(in, "%d", &number); 1308 fscanf(in, "%s", name); 1309 set_student_name(number, name); 1310 } 1311 else if (s[0] == 'C') { 1312 char classes[300]; 1313 int number; 1314 fscanf(in, "%d", &number); 1315 fscanf(in, "%s", classes); 1316 set_student_classnumber(number, classes); 1317 ListNode *pt; 1318 pt = Search(classes, 1); 1319 insert_data(pt, number, 1); 1320 } 1321 else if (s[0] == 'D') { 1322 char department[300]; 1323 int number; 1324 fscanf(in, "%d", &number); 1325 fscanf(in, "%s", department); 1326 set_student_department(number, department); 1327 ListNode *pt; 1328 pt = Search(department, 1); 1329 insert_data(pt, number, 1); 1330 } 1331 else if (s[0] == 'S') { 1332 int number; 1333 char coursename[30]; 1334 int score; 1335 fscanf(in, "%s", coursename); 1336 fscanf(in, "%d%d", &number, &score); 1337 int index = get_student_index(number); 1338 if (index<0)//若没有该学生信息 1339 index = student_insert(number);//插入该学生信息 1340 ListNode *pt; 1341 pt = Search(coursename); 1342 insert_data(pt, number, score); 1343 } 1344 } 1345 } 1346 } 1347 1348 void Save_course(){//保存课程 1349 const int Max_PATH = 100; 1350 TCHAR szBuffer[Max_PATH] = { 0 }; //保存文件名 1351 HWND m_hWnd = GetHWnd();//获取窗口句柄 1352 OPENFILENAME ofn = { 0 }; 1353 ofn.lStructSize = sizeof(ofn); 1354 ofn.hwndOwner = m_hWnd; 1355 ofn.lpstrFilter = _T("TxT文件(*.txt)*.txt所有文件(*.*)*.*");//要选择的文件后缀 1356 ofn.lpstrInitialDir = _T("C:\\Users\\Administrator\\Desktop\\");//默认的文件路径 1357 ofn.lpstrFile = szBuffer;//存放文件的缓冲区 1358 ofn.nMaxFile = sizeof(szBuffer) / sizeof(*szBuffer); 1359 ofn.nFilterIndex = 0; 1360 ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER;//标志如果是多选要加上OFN_ALLOWMULTISELECT 1361 BOOL bSel = GetOpenFileName(&ofn); 1362 if (bSel == false) { 1363 Message("请检查文件输入", "请检查文件输入"); 1364 return; 1365 } 1366 FILE* out = NULL; 1367 out = fopen(szBuffer, "w+");//写入方式打开文件 1368 if (out == NULL) {//文件打开失败 1369 Message("请检查文件是否存在", "请检查文件是否存在"); 1370 return; 1371 } 1372 char classes[300]; 1373 InputBox(classes,250,"请输入要查询的课程名称","请输入",NULL,0,0,true);//弹出提示输入框 读取用户输入 1374 ListNode* pt; 1375 pt = Search(classes); 1376 fprintf(out,"%7s %7s %7s %7s\n", "名次", "学号", "成绩","名字"); 1377 pt->tree_score.out(pt->tree_score.Get_head(), 2,out); 1378 fclose(out); 1379 Message("输出成功", "成功"); 1380 } 1381 1382 void save_class(){//输出课程信息至文件 1383 const int Max_PATH = 100; 1384 TCHAR szBuffer[Max_PATH] = { 0 }; //保存文件名 1385 HWND m_hWnd = GetHWnd();//获取窗口句柄 1386 OPENFILENAME ofn = { 0 }; 1387 ofn.lStructSize = sizeof(ofn); 1388 ofn.hwndOwner = m_hWnd; 1389 ofn.lpstrFilter = _T("TxT文件(*.txt)*.txt所有文件(*.*)*.*");//要选择的文件后缀 1390 ofn.lpstrInitialDir = _T("C:\\Users\\Administrator\\Desktop\\");//默认的文件路径 1391 ofn.lpstrFile = szBuffer;//存放文件的缓冲区 1392 ofn.nMaxFile = sizeof(szBuffer) / sizeof(*szBuffer); 1393 ofn.nFilterIndex = 0; 1394 ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER;//标志如果是多选要加上OFN_ALLOWMULTISELECT 1395 BOOL bSel = GetOpenFileName(&ofn); 1396 if (bSel == false) { 1397 Message("请检查文件输入", "请检查文件输入"); 1398 return; 1399 } 1400 FILE* out = NULL; 1401 out = fopen(szBuffer, "w+");//写入方式打开文件 1402 if (out == NULL) {//文件打开失败 1403 Message("请检查文件是否存在", "请检查文件是否存在"); 1404 return; 1405 } 1406 char classes[300]; 1407 InputBox(classes,250,"请输入要查询的班级或系别名称","请输入",NULL,0,0,true);//弹出提示输入框 读取用户输入 1408 ListNode* pt; 1409 pt = Search(classes); 1410 num_vector.clear(); 1411 pt->tree_number.out3(pt->tree_number.Get_head(), &num_vector); 1412 if (num_vector.size() == 0) { 1413 fprintf(out,"该列表没有成员\n"); 1414 fclose(out); 1415 return; 1416 } 1417 Score_vector = new ScoreData[num_vector.size()];//创立一个该班人数大小的线性表 1418 int i; 1419 for (i = 0; i < num_vector.size(); i++) { 1420 Score_vector[i].number = num_vector[i];//存储学号 1421 Score_vector[i].score = getsumscore(Score_vector[i].number); 1422 } 1423 Quicksort(Score_vector, 0, num_vector.size() - 1); 1424 fprintf(out, "%7s %7s %7s %7s\n", "排名", "学号", "分数","名字"); 1425 for (i = 0; i <= num_vector.size() - 1; i++) { 1426 get_name(Score_vector[i].number); 1427 fprintf(out, "%7d %7d %7d %7s\n", i + 1, Score_vector[i].number, Score_vector[i].score,name); 1428 } 1429 Message("输出成功","输出成功"); 1430 fclose(out); 1431 } 1432 void exit(){ 1433 closegraph();// 关闭绘图窗口 1434 } 1435 void deal() { 1436 while (1) { 1437 int p = getmouse(); 1438 if (p == 1) { 1439 openfile(); 1440 } 1441 else if (p == 2) { 1442 Save_course(); 1443 } 1444 else if (p == 3) { 1445 save_class(); 1446 } 1447 else if (p == 4) { 1448 exit(); 1449 return; 1450 } 1451 } 1452 } 1453 1454 void grap()//图形化界面 1455 { 1456 initgraph(X, Y);//创立界面 1457 HWND hwnd = GetHWnd();//获取窗口句柄 1458 SetWindowText(hwnd, "学生成绩管理系统图形化操作界面 BY:WYS"); 1459 IMAGE img1;//初始窗口背景 1460 loadimage(&img1, _T("Main_g.jpg"), X, Y, true); 1461 putimage(0, 0, &img1, SRCCOPY);//在窗口上绘制背景图片 第三个参数为 绘制出的像素颜色=原图形颜色 1462 IMAGE img2, img2f;//保存窗口按钮 1463 loadimage(&img1, _T("Main_g.jpg"), X, Y, true); 1464 putimage(0, 0, &img1, SRCCOPY);//在窗口上绘制背景图片 第三个参数为 绘制出的像素颜色=原图形颜色 1465 1466 loadimage(&img2f, _T("Opy.jpg"), X / 4, Y / 5, true);//加载标题图片-掩码 1467 putimage(100, 20, &img2f, NOTSRCERASE);//打印标题图片-掩码 1468 loadimage(&img2, _T("Op.jpg"), X / 4, Y / 5, true);//加载标题图片 1469 putimage(100, 20, &img2, SRCINVERT);//打印标题图片 1470 1471 loadimage(&img2f, _T("bcky.jpg"), X / 4, Y / 5, true);//加载标题图片-掩码 1472 putimage(500, 20, &img2f, NOTSRCERASE);//打印标题图片-掩码 1473 loadimage(&img2, _T("bck.jpg"), X / 4, Y / 5, true);//加载标题图片 1474 putimage(500, 20, &img2, SRCINVERT);//打印标题图片 1475 1476 loadimage(&img2f, _T("bcby.jpg"), X / 4, Y / 5, true);//加载标题图片-掩码 1477 putimage(100, 250, &img2f, NOTSRCERASE);//打印标题图片-掩码 1478 loadimage(&img2, _T("bcb.jpg"), X / 4, Y / 5, true);//加载标题图片 1479 putimage(100, 250, &img2, SRCINVERT);//打印标题图片 1480 1481 loadimage(&img2f, _T("exitf.jpg"), X / 4, Y / 5, true);//加载标题图片-掩码 1482 putimage(500, 250, &img2f, NOTSRCERASE);//打印标题图片-掩码 1483 loadimage(&img2, _T("exit.jpg"), X / 4, Y / 5, true);//加载标题图片 1484 putimage(500, 250, &img2, SRCINVERT);//打印标题图片 1485 deal();//处理 1486 } 1487 1488 void Main_menu() {//主菜单 1489 while (1) { 1490 Screen_clear();//清屏 1491 printf("\t\t欢迎使用学生成绩管理系统\n"); 1492 printf("\t\t\t请输入操作命令\n"); 1493 printf("\t\t\t1.录入/修改系统\n"); 1494 printf("\t\t\t2.查询系统\n"); 1495 printf("\t\t\t3.班/系 成绩分析系统\n"); 1496 printf("\t\t\t4.课程成绩分析系统\n"); 1497 printf("\t\t\t5.排名系统\n"); 1498 printf("\t\t\t6.退出程序\n"); 1499 printf("\t\t\t7.拓展功能:图形化操作模式\n"); 1500 printf("\t\t\t请您输入操作指令\n"); 1501 printf("\t\t\t"); 1502 char s; 1503 s = getchar(); 1504 if (!(s <= '7'&&s >= '1')) {//检查输入命令 1505 fflush(stdin);//清空输入缓冲区 1506 continue; 1507 } 1508 int order = s - '0';//获取命令编号 1509 if (order == 1) 1510 Input_System(); 1511 else if (order == 2) 1512 Output_System(); 1513 else if (order == 3) 1514 Analyze_System(); 1515 else if (order == 4) 1516 Course_System(); 1517 else if (order == 5) 1518 Rank_System(); 1519 else if (order == 6) 1520 exit(0); 1521 else if (order == 7) 1522 grap(); 1523 } 1524 } 1525 1526 int main() { 1527 srand(time(0)); 1528 Main_menu(); 1529 return 0; 1530 }