这个程序打印效果不好,而且不好修改 横线----
可以封装多个printf() 每个打印固定数量的 - 修改也比较好改;
但是中文和英文字宽不一样 推荐都用中文符号
student.h
//
// Created by lishi on 2022/10/17.
//
#ifndef STUDENT_MANAGEMENT_SYSTEM_STUDENT_H
#define STUDENT_MANAGEMENT_SYSTEM_STUDENT_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
struct student
{
int number;
char name[100];
char *name_pt_test;
float score;
struct student *next;
};
typedef struct student Student;
struct head_of_Student
{
int list_length;
Student *first;
Student *last;
int list_number_max;
};
typedef struct head_of_Student Student_head;
Student *node_information_write_without_output(Student *node);
Student *node_information_write_with_output(Student *node);
Student *node_create_without_information(void);
Student *node_create_with_information(void);
int show_node(Student * node);
int show_list(Student_head *head);
int get_list_length(Student_head *head);
Student *node_search_by_number(Student_head *head, int number);
Student *node_search_by_number_simple(Student *node, int number);
Student *node_search_by_index(Student_head *head, int index);
Student *node_search_by_name(Student_head *head, char *name);
Student *node_search_by_score(Student_head *head, float score);
void list_sort_by_number(Student_head *head);
void node_insert_by_number(Student_head *head, Student *node_insert);
void node_del_by_number(Student_head *head, Student *node_delete);
void list_free_by_recursive(Student *node);
void list_free_by_while(Student_head *head);
void list_reversal(Student_head *head);
void create_list_by_head_unknown_count(Student_head *head);
void create_list_by_head_known_count(Student_head *head);
void list_file_write(Student_head *head);
int list_file_read(Student_head *head);
int node_add_check(Student_head *head, Student *new_node);
void change_menu(Student_head *head);
#endif //STUDENT_MANAGEMENT_SYSTEM_STUDENT_H
student.c
//
// Created by lishi on 2022/10/17.
//
#include "student.h"
Student *node_information_write_without_output(Student *node)
{
scanf("%d%s%f", &node->number, node->name, &node->score);
while(getchar() != '\n')continue;
node->next = NULL;
return node;
}
Student *node_information_write_with_output(Student *node)
{
printf(
"-----------------------------\n"
"|输入学生 学号, 姓名, 成绩 |\n"
"-----------------------------\n");
scanf("%d%s%f", &node->number, node->name, &node->score);
while(getchar() != '\n')continue;
node->next = NULL;
return node;
}
Student *node_create_without_information(void)
{
Student *new_node = (Student *)malloc(sizeof(Student));
if(!new_node)
{
fprintf(stderr, "error : create node\n");
exit(-1);
}
new_node = node_information_write_without_output(new_node);
return new_node;
}
Student *node_create_with_information(void)
{
Student *new_node = (Student *)malloc(sizeof(Student));
if(!new_node)
{
fprintf(stderr, "error : create node\n");
exit(-1);
}
new_node = node_information_write_with_output(new_node);
return new_node;
}
int show_node(Student * node)
{
if(!node)
{
return 0;
}
printf("|学号:%05d |姓名:%-6s |成绩:%6.2f|\n",
node->number, node->name, node->score);
return 1;
}
int show_list(Student_head *head)
{
if(!head->first)
{
printf("--------------------------------------\n"
"|没有学生信息 |\n"
"--------------------------------------\n");
return 0;
}
Student *temp = head->first;
printf("--------------------------------------\n");
while(temp)
{
show_node(temp);
temp = temp->next;
}
printf("--------------------------------------\n"
"|共 %d 名学生 |\n"
"--------------------------------------\n",
head->list_length);
return head->list_length;
}
int get_list_length(Student_head *head)
{
int list_length = 0;
if(!head->first)
{
return list_length;
}
Student *temp = head->first;
while(temp)
{
list_length++;
temp = temp->next;
}
return list_length;
}
Student *node_search_by_number(Student_head *head, int number)
{
int i = 0;
Student *node_search = head->first;
for(; i < head->list_length; i++)
{
if(node_search->number == number)
{
break;
}
else
{
node_search = node_search->next;
}
}
if(i == head->list_length)
{
return NULL;
}
return node_search;
}
Student *node_search_by_number_simple(Student *node, int number)
{
int i = 0;
while(node)
{
if(node->number == number)
{
break;
}
else
{
node = node->next;
}
}
if(!node)
{
return NULL;
}
return node;
}
Student *node_search_by_index(Student_head *head, int index)
{
if(index < 1 || index > head->list_length)
{
return NULL;
}
Student *node_search = head->first;
for(int i = 0; i < index - 1; i++)
{
node_search = node_search->next;
}
return node_search;
}
Student *node_search_by_name(Student_head *head, char *name)
{
static int i = 0;
Student *node_search = head->first;
for (int j = 0; (j < i && i); j++)
{
node_search = node_search->next;
}
for (; i < head->list_length; i++)
{
if (!strcmp(node_search->name, name))
{
i++;
break;
}
else
{
node_search = node_search->next;
}
}
if (i == head->list_length)
{
i = 0;
return NULL;
}
return node_search;
}
Student *node_search_by_score(Student_head *head, float score)
{
static int i = 0;
Student *node_search = head->first;
for (int j = 0; (j < i&& i); j++)
{
node_search = node_search->next;
}
for (; i < head->list_length; i++)
{
if (node_search->score == score)
{
i++;
break;
}
else
{
node_search = node_search->next;
}
}
if (i == head->list_length)
{
i = 0;
return NULL;
}
return node_search;
}
void list_sort_by_number(Student_head *head)
{
if(head->list_length < 2)
{
return;
}
Student *old_first = head->first;
//临时结构指针,最大数
Student* temp;
Student* number_max;
//新链表开头
Student* new_first = NULL;
while (old_first)
{
//循环找包含最大值 结构
temp = old_first;
number_max = old_first;
while (temp)
{
if (number_max->number < temp->number)
{
number_max = temp;
}
temp = temp->next;
}
//从原始链表移除节点;
Student* remove_node = number_max;
Student* before_remove_node = old_first;
if (remove_node == old_first)//头
{
old_first = old_first->next;
}
else//中间 和尾部
{
while (1)
{
if (!before_remove_node->next->next || remove_node->number == before_remove_node->next->number)
{
break;
}
before_remove_node = before_remove_node->next;
}
before_remove_node->next = before_remove_node->next->next;
head = head;
}
//头插法创建列表
number_max->next = new_first;
new_first = number_max;
}
head->first = new_first;
return;
}
void node_insert_by_number(Student_head *head, Student *node_insert)
{
if(node_insert->number <head->first->number)
{
node_insert->next = head->first;
head->first = node_insert;
return;
}
Student *before_insert_node = head->first;
while(1)
{
if(before_insert_node->next->number > node_insert->number || !before_insert_node->next)
{
node_insert->next = before_insert_node->next;
before_insert_node->next = node_insert;
return;
}
before_insert_node = before_insert_node->next;
}
}
void node_del_by_number(Student_head *head, Student *node_delete)
{
Student *before_del_node = head->first;
if(node_delete == head->first)
{
head->first = head->first->next;
free(before_del_node);
return;
}
while(1)
{
if(!before_del_node->next->next || node_delete == before_del_node->next)
{
break;
}
before_del_node = before_del_node->next;
}
before_del_node->next = before_del_node->next->next;
free(node_delete);
return;
}
void list_free_by_recursive(Student *node)
{
if(!node)
{
return;
}
else
{
list_free_by_recursive(node->next);
free(node);
return;
}
}
void list_free_by_while(Student_head *head)
{
Student *temp;
while (head->first)
{
temp = head->first;
head->first = head->first->next;
free(temp);
}
return;
}
void list_reversal(Student_head *head)
{
Student *old_first = head->first;
Student *new_first = NULL;
Student *temp = NULL;
while(old_first)
{
temp = old_first;
old_first = old_first->next;
temp->next = new_first;
new_first = temp;
}
head->first = new_first;
}
void create_list_by_head_unknown_count(Student_head *head)
{
int is_first_enter = 1;
char is_continue;
while (1)
{
if(is_first_enter)
{
system("clear");
Student *new_node = node_create_with_information();
if(node_add_check(head, new_node))
{
is_first_enter = 0;
continue;
}
new_node->next = head->first;
head->first = new_node;
(head->list_length)++;
is_first_enter = 0;
continue;
}
else
{
system("clear");
show_list(head);
printf("-----------------------------\n"
"|要继续添加学生信息吗?[y/n] |\n"
"-----------------------------\n");
}
is_continue = getchar();
while (getchar() != '\n') continue;
if (is_continue == 'n' || is_continue == 'N')
{
return;
}
else if(is_continue == 'y' || is_continue == 'Y')
{
Student *new_node = node_create_with_information();
if(node_add_check(head, new_node))
{
continue;
}
new_node->next = head->first;
head->first = new_node;
(head->list_length)++;
continue;
}
else
{
printf("--------------------------\n"
"|输入有误 再试一次 |\n"
"--------------------------\n");
usleep(300 * 1000);
continue;
}
}
}
void create_list_by_head_known_count(Student_head *head)
{
system("clear");
int list_len;
printf("-----------------------------\n"
"要添加多少个学生? ");
scanf("%d", &list_len);
while (getchar() != '\n') continue;
for(int i = 1; i <= list_len; i++)
{
printf("-----------------------------\n");
printf("|输入第%d个学生的 |\n"
"|学号, 姓名, 成绩: |\n"
"-----------------------------\n", i);
Student *new_node = node_create_without_information();
// scanf("%d%s%f", &new_node->number, new_node->name, &new_node->score);
// while (getchar() != '\n') continue;
if(node_add_check(head, new_node))
{
i--;
continue;
}
new_node->next = head->first;
head->first = new_node;
(head->list_length)++;
}
if(list_len < 1) list_len = 0;
printf("-----------------------------\n"
"|共添加%d个学生 |\n"
"|按下回车键继续 |\n"
"-----------------------------\n", list_len);
while (getchar() != '\n') continue;
return;
}
void list_file_write(Student_head *head)
{
Student *temp = head->first;
FILE *list_file = fopen("./student.save", "wb");
if(!list_file)
{
perror("open file error\n");
return;
}
while(temp)
{
fwrite(temp, sizeof(Student), 1,list_file);
temp = temp->next;
}
fclose(list_file);
list_file = NULL;
return;
}
int list_file_read(Student_head *head)
{
int readed = 0;
FILE *list_file = fopen("./student.save", "rb");
if(!list_file)
{
// perror("open file error\n");
return 0;
}
int is_read_ok;
Student *temp = NULL;
while(1)
{
Student *new_node = malloc(sizeof(Student));
is_read_ok = fread(new_node, sizeof(Student), 1, list_file);
if(is_read_ok < 1)
{
free(new_node);
break;
}
new_node->next = temp;
temp = new_node;
readed++;
}
head->first = temp;
return readed;
}
int node_add_check(Student_head *head, Student *new_node)
{
if(new_node->number < 1)
{
printf("-----------------------------\n"
"|学号不得小于1,未能添加 |\n"
"|按下回车键继续 |\n"
"-----------------------------\n");
while (getchar() != '\n') continue;
free(new_node);
return 1;
}
if(new_node->number > 99999)
{
printf("-----------------------------\n"
"|学号不得大于99999 |\n"
"|未能添加,按下回车键继续 |\n"
"-----------------------------\n");
while (getchar() != '\n') continue;
free(new_node);
return 2;
}
if(node_search_by_number(head, new_node->number))
{
printf("-----------------------------\n"
"|学号重复,未能添加 |\n"
"|按下回车键继续 |\n"
"-----------------------------\n");
while (getchar() != '\n') continue;
free(new_node);
return 3;
}
return 0;
}
menu.h
//
// Created by lishi on 2022/10/17.
//
#ifndef STUDENT_MANAGEMENT_SYSTEM_MENU_H
#define STUDENT_MANAGEMENT_SYSTEM_MENU_H
#include "student.h"
extern char first_menu_select;
extern char second_menu_select;
char main_menu(void);
char first_show_menu(void);
void list_show_menu(Student_head *head);
void list_sort_menu(Student_head *head);
char node_search_menu(void);
void node_search_by_number_menu(Student_head *head);
void node_search_by_name_menu(Student_head *head);
void node_search_by_score_menu(Student_head *head);
void node_insert_menu(Student_head *head);
void node_del_menu(Student_head *head);
void save_menu(Student_head *head);
void import_menu(Student_head *head);
void create_menu(void);
#endif //STUDENT_MANAGEMENT_SYSTEM_MENU_H
menu.c
//
// Created by lishi on 2022/10/17.
//
//
// Created by lishi on 2022/10/17.
//
#include "menu.h"
char first_menu_select = 0;
char second_menu_select = 0;
char main_menu(void)
{
while (1)
{
system("clear");
printf(
"--------------------------\n"
"|输入数字选择功能 |\n"
"--------------------------\n"
"| [1] 显示学生信息 |\n"
"| [2] 学生信息排序 |\n"
"| [3] 查找学生信息 |\n"
"| [4] 插入学生信息 |\n"
"| [5] 删除学生信息 |\n"
"| [6] 保存学生信息 |\n"
"| [7] 修改学生信息 |\n"
"| [8] 退出 |\n"
"--------------------------\n");
first_menu_select = getchar();
while (getchar() != '\n')
continue;
if (first_menu_select < '1' || first_menu_select > '8')
{
printf("--------------------------\n"
"|输入有误 再试一次 |\n"
"--------------------------\n");
usleep(300 * 1000);
continue;
}
else
break;
}
return first_menu_select;
}
char first_show_menu(void)
{
while (1)
{
system("clear");
printf(
"--------------------------\n"
"|输入数字选择功能 |\n"
"--------------------------\n"
"| [1] 开始输入学生信息 |\n"
"| [2] 文件导入学生信息 |\n"
"| [3] 退出 |\n"
"--------------------------\n");
first_menu_select = getchar();
while (getchar() != '\n')
continue;
if (first_menu_select < '1' || first_menu_select > '3')
{
printf("--------------------------\n"
"|输入有误 再试一次 |\n"
"--------------------------\n");
usleep(300 * 1000);
continue;
}
else
break;
}
return first_menu_select;
}
void list_show_menu(Student_head *head)
{
system("clear");
printf("--------------------------------------\n"
"|学生列表 : |\n");
show_list(head);
printf("--------------------------\n"
"|显示完成 回车继续 |\n"
"--------------------------\n");
while (getchar() != '\n')
continue;
return;
}
void list_sort_menu(Student_head *head)
{
list_sort_by_number(head);
system("clear");
printf("--------------------------------------\n"
"|排序后学生列表 : |\n");
show_list(head);
printf("--------------------------\n"
"|排序完成 回车继续 |\n"
"--------------------------\n");
while (getchar() != '\n')
continue;
return;
}
char node_search_menu(void)
{
while (1)
{
system("clear");
printf(
"--------------------------\n"
"|输入数字选择功能 |\n"
"--------------------------\n"
"| [1] 通过学号查找 |\n"
"| [2] 通过姓名查找 |\n"
"| [3] 通过成绩查找 |\n"
"| [4] 返回 |\n"
"--------------------------\n");
second_menu_select = getchar();
while (getchar() != '\n')
continue;
if (second_menu_select < '1' || second_menu_select > '4')
{
printf(
"--------------------------\n"
"|输入有误 重新输入 |\n"
"--------------------------\n"
);
usleep(300 * 1000);
continue;
}
else
break;
}
return second_menu_select;
}
void node_search_by_number_menu(Student_head *head)
{
int searched_count = 0;
system("clear");
int search_number;
Student *searched = NULL;
printf("--------------------------------------\n"
"|输入要查找的学生的学号: ");
scanf("%d", &search_number);
while (getchar() != '\n')continue;
printf("--------------------------------------\n");
searched = node_search_by_number(head, search_number);
if (searched == NULL)
{
printf(
"--------------------------------------\n"
"|没有查找到学生信息 |\n"
"--------------------------------------\n");
}
else
{
show_node(searched);
printf("--------------------------------------\n");
searched_count++;
}
printf("--------------------------\n"
"|查找到%d个学生 回车继续 |\n"
"--------------------------\n", searched_count);
while (getchar() != '\n')
continue;
return;
}
void node_search_by_name_menu(Student_head *head)
{
system("clear");
char search_name[100];
int searched_count = 0;
Student *searched = NULL;
printf("--------------------------------------\n"
"|输入要查找的学生的姓名: ");
scanf("%s", search_name);
while (getchar() != '\n')continue;
printf("--------------------------------------\n");
do
{
searched = node_search_by_name(head, search_name);
if (searched == NULL)
{
break;
}
else
{
show_node(searched);
searched_count++;
}
} while (1);
printf("--------------------------------------\n");
printf("--------------------------\n"
"|查找到%d个学生 回车继续 |\n"
"--------------------------\n",
searched_count);
while (getchar() != '\n')
continue;
return;
}
void node_search_by_score_menu(Student_head *head)
{
system("clear");
float search_score;
int searched_count = 0;
Student *searched = NULL;
printf("--------------------------------------\n"
"|输入要查找的学生的成绩 : ");
scanf("%f", &search_score);
while (getchar() != '\n')
continue;
printf("--------------------------------------\n");
do
{
searched = node_search_by_score(head, search_score);
if (searched == NULL)
{
break;
}
else
{
show_node(searched);
searched_count++;
}
} while (1);
printf("--------------------------------------\n");
printf("--------------------------\n"
"|查找到%d个学生 回车继续 |\n"
"--------------------------\n",
searched_count);
while (getchar() != '\n')
continue;
return;
}
void node_insert_menu(Student_head *head)
{
system("clear");
Student *new_node = node_create_with_information();
if (node_add_check(head, new_node))
{
return;
}
list_sort_by_number(head);
node_insert_by_number(head, new_node);
head->list_length++;
printf("-----------------------------\n"
"|插入完成 回车继续 |\n"
"-----------------------------\n");
while (getchar() != '\n')
continue;
return;
}
void node_del_menu(Student_head *head)
{
int del_number;
system("clear");
printf("--------------------------\n"
"|输入要删除的学生的学号: |\n"
"|(不想删除了可以输入0 ) |\n"
"--------------------------\n");
scanf("%d", &del_number);
while (getchar() != '\n')
continue;
Student *del_node = node_search_by_number(head, del_number);
if (!del_node)
{
printf("--------------------------\n"
"|没有该学生 回车继续 |\n"
"--------------------------\n");
}
else
{
node_del_by_number(head, del_node);
head->list_length--;
printf("--------------------------\n"
"|删除完成 回车继续 |\n"
"--------------------------\n");
}
while (getchar() != '\n')
continue;
return;
}
void save_menu(Student_head *head)
{
list_file_write(head);
printf("--------------------------\n"
"|保存完成 回车继续 |\n"
"--------------------------\n");
while (getchar() != '\n')
continue;
return;
}
void import_menu(Student_head *head)
{
system("clear");
int is_ok = list_file_read(head);
if (!is_ok)
{
printf("--------------------------\n"
"|没有文件 |\n"
"--------------------------\n");
usleep(300 * 1000);
return;
}
head->list_length = get_list_length(head);
show_list(head);
printf("--------------------------\n"
"|导入完成 回车继续 |\n"
"--------------------------\n");
while (getchar() != '\n')
continue;
return;
}
void create_menu(void)
{
while (1)
{
system("clear");
printf(
"--------------------------\n"
"|输入数字选择功能 |\n"
"--------------------------\n"
"| [1] 你知道学生总数 |\n"
"| [2] 不知道学生总数 |\n"
"| [3] 返回 |\n"
"--------------------------\n");
second_menu_select = getchar();
while (getchar() != '\n')
continue;
if (second_menu_select < '1' || second_menu_select > '3')
{
printf("--------------------------\n"
"|输入有误 再试一次 |\n"
"--------------------------\n");
usleep(300 * 1000);
continue;
}
else
break;
}
return;
}
void change_menu(Student_head *head)
{
system("clear");
int change_node_number;
printf(
"--------------------------\n"
"|输入要修改的学生的学号: |\n"
"--------------------------\n");
scanf("%d", &change_node_number);
while(getchar() != '\n') continue;
Student *change_node = node_search_by_number(head, change_node_number);
if(!change_node)
{
printf(
"--------------------------\n"
"|没有这个学生 回车继续 |\n"
"--------------------------\n");
while (getchar() != '\n')continue;
return;
}
while (1)
{
system("clear");
printf("--------------------------------------\n");
show_node(change_node);
printf("--------------------------------------\n");
printf(
"--------------------------\n"
"|要修改哪项内容? |\n"
"--------------------------\n"
"| [1] 姓名 |\n"
"| [2] 成绩 |\n"
"| [3] 返回 |\n"
"--------------------------\n");
second_menu_select = getchar();
while (getchar() != '\n')
continue;
if (second_menu_select < '1' || second_menu_select > '3')
{
printf(
"--------------------------\n"
"|输入有误 重新输入 |\n"
"--------------------------\n"
);
usleep(300 * 1000);
continue;
}
else
break;
}
switch (second_menu_select)
{
case '1':
{
char change_node_name[100];
printf(
"--------------------------\n"
"|输入更改后的姓名: |\n"
"--------------------------\n");
scanf("%s", change_node_name);
while(getchar() != '\n') continue;
strcpy(change_node->name, change_node_name);
break;
}
case '2':
{
float change_node_score;
printf(
"--------------------------\n"
"|输入更改后的成绩: |\n"
"--------------------------\n");
scanf("%f", &change_node_score);
while(getchar() != '\n') continue;
change_node->score = change_node_score;
break;
}
case '3':
{
return;
}
}
system("clear");
printf("--------------------------------------\n");
show_node(change_node);
printf("--------------------------------------\n");
printf(
"--------------------------\n"
"|更改完成 回车继续 |\n"
"--------------------------\n");
while (getchar() != '\n') continue;
return;
}
main.c
#include "menu.h"
#include "student.h"
int is_first_open = 1;
int main(void)
{
Student_head *head = (Student_head *)malloc(sizeof(Student_head));
head->first = NULL;
head->last = NULL;
head->list_length = 0;
while(1)
{
if(is_first_open)
{
first_show_menu();
}
else
{
main_menu();
}
if(is_first_open)
{
switch (first_menu_select)
{
case '1':
{
create_menu();
switch (second_menu_select)
{
case '1':
{
is_first_open = 0;
create_list_by_head_known_count(head);
break;
}
case '2':
{
is_first_open = 0;
create_list_by_head_unknown_count(head);
break;
}
case '3':
{
is_first_open = 1;
break;
}
default :
{
break;
}
}
break;
}
case '2':
{
is_first_open = 0;
import_menu(head);
break;
}
case '3':
{
system("clear");
printf(
"--------------------------\n"
"|程序退出 |\n"
"--------------------------\n");
exit(0);
}
}
}
else
{
switch (first_menu_select)
{
case '1':
{
list_show_menu(head);
break;
}
case '2':
{
list_sort_menu(head);
break;
}
case '3':
{
node_search_menu();
list_sort_by_number(head);
switch (second_menu_select)
{
case '1':
{
node_search_by_number_menu(head);
break;
}
case '2':
{
node_search_by_name_menu(head);
break;
}
case '3':
{
node_search_by_score_menu(head);
break;
}
case '4':
{
break;
}
}
break;
}
case '4':
{
node_insert_menu(head);
break;
}
case '5':
{
node_del_menu(head);
break;
}
case '6':
{
save_menu(head);
break;
}
case '7':
{
change_menu(head);
break;
}
case '8':
{
system("clear");
printf(
"--------------------------\n"
"|程序退出 |\n"
"--------------------------\n");
exit(0);
}
}
}
}
}