完整代码在最后面。
这次我们的目标是用C语言实现新生报道注册管理信息系统。
这是我们要用到 C 语言中的三个头文件,分别是:
#include <stdio.h>:它包含了一些输入输出的函数,例如printf()和scanf()。
#include <stdlib.h>:它包含了实用的函数,例如动态内存分配函数malloc() 和free()。
#include <string.h>:它包含了一些操作字符串的函数,例如strcpy() 和strcat()。
1.主要框架
我们首先定义了一个表示学生的结构体,然后声明了要用到的函数,接着编写主函数,搭建好了大致的系统框架:
// 定义一个表示学生的结构体 struct student { char nam[10]; // 学生姓名 char sex[4]; // 学生性别 char spec[20]; // 学生专业 char classid[10]; // 学生班级ID char phone[15]; // 学生电话号码 char bedroom[8]; // 学生宿舍号码 }; // 函数声明 void createdata(struct student *stu, int *len); // 注册学生信息 void add(struct student *stu, int *len); // 增加学生信息 void delete_student(struct student *stu, int *len); // 删除学生信息 void search_name(struct student *stu, int len); // 按姓名查询 void search_class(struct student *stu, int len); // 按班级查询 void search_specialty(struct student *stu, int len); // 按专业查询 void print_fun(struct student *stu, int len); // 打印学生信息 // 主函数 int main() { int choice; struct student p[1024]; int len = 0; while (1) { printf("\n 新生报到信息注册系统\n\n"); printf("**********************************************************************\n"); printf("1. 注册学生信息\n"); printf("2. 增加学生信息\n"); printf("3. 删除学生信息\n"); printf("4. 按姓名查询\n"); printf("5. 按班级查询\n"); printf("6. 按专业查询\n"); printf("7. 打印学生信息\n"); printf("8. 退出系统\n"); printf("**********************************************************************\n"); printf("请输入选项:"); scanf("%d", &choice); switch (choice) { case 1: // 注册学生信息 createdata(p, &len); break; case 2: // 增加学生信息 add(p, &len); break; case 3: // 删除学生信息 delete_student(p, &len); break; case 4: // 按姓名查询 search_name(p, len); break; case 5: // 按班级查询 search_class(p, len); break; case 6: // 按专业查询 search_specialty(p, len); break; case 7: // 打印学生信息 print_fun(p, len); break; case 8: // 退出系统 printf("谢谢您的使用!\n\n"); exit(0); // 退出程序 default: printf("输入有误!请重新输入。\n\n"); break; } } return 0; }
接下来,我们要编写前面声明了的函数。
2.写入文件
// 定义一个名为regis的函数 // 参数为一个指向struct student类型的指针p和一个整型变量len void regis(struct student *p, int len) { // 定义一个FILE类型的指针,用于打开/关闭文件 FILE *fp; // 打开名为student_info.txt的文件,使用写入模式打开,即将内容写入到文件尾部 fp = fopen("student_info.txt", "w"); // 循环遍历学生信息数组 for (int i = 0; i < len; i++) { // 将学生信息按指定格式写入到文件中 fprintf(fp, "%s %s %s %s %s %s\n", p[i].nam, p[i].sex, p[i].spec, p[i].classid, p[i].phone, p[i].bedroom); } // 关闭文件 fclose(fp); }
函数regis用于将结构体数组中的数据写入到文件中。它首先使用fopen函数打开一个名为"student_info.txt"的文件,并指定模式为"w",表示以写入方式打开文件。然后,使用fprintf函数将结构体数组中的数据按照指定的格式写入文件。最后,使用fclose函数关闭文件。
3.读取文件
// 定义一个名为read_data的函数 // 参数为一个指向struct student类型的指针p和一个指向整型变量len的指针 void read_data(struct student *p, int *len) { // 定义一个FILE类型的指针,用于打开/关闭文件 FILE *fp; // 打开名为student_info.txt的文件,使用读取模式打开 fp = fopen("student_info.txt", "r"); // 检查文件是否打开成功 if (fp == NULL) { printf("文件打开失败\n"); return; } // 循环读取文件中的学生信息,直到遇到文件结尾或读取出错 while (fscanf(fp, "%s %s %s %s %s %s", p[*len].nam, p[*len].sex, p[*len].spec, p[*len].classid, p[*len].phone, p[*len].bedroom) == 6) { // 每读取一行信息,增加len的值 (*len)++; } // 关闭文件 fclose(fp); }
函数read_data用于从文件中读取数据并存入结构体数组中。它首先使用fopen函数打开名为"student_info.txt"的文件,并指定模式为"r",表示以只读方式打开文件。然后,它使用fscanf函数按照指定的格式逐行读取文件中的数据,并将读取的数据存入结构体数组p中的相应位置。同时,使用指针len来记录读取的数据行数。最后,使用fclose函数关闭文件。
regis和read_data这两个函数配合使用可以实现将结构体数组中的数据写入文件,以及从文件中读取数据并存入结构体数组中的功能。
4.注册学生信息
void createdata(struct student *p, int *len) { int n; // 定义变量n,用于存储学生人数 printf("报到学生人数:"); scanf("%d", &n); // 从用户输入中获取学生人数信息 printf("请输入学生信息:\n"); // 循环获取每个学生的信息,共n次 for (int i = 0; i < n; i++) { printf("学生%d:\n", i+1); printf("姓名:"); scanf("%s", p[i].nam); printf("性别:"); scanf("%s", p[i].sex); printf("专业:"); scanf("%s", p[i].spec); printf("班级:"); scanf("%s", p[i].classid); printf("电话号码:"); scanf("%s", p[i].phone); printf("宿舍号:"); scanf("%s", p[i].bedroom); printf("\n"); } *len = n; // 将len的值设为学生人数n regis(p, n); // 将学生信息写入文件 }
首先,该函数会从用户输入中获取学生人数,并将其存储在变量`n`中。然后,函数会通过循环获取每个学生的信息,并将其存储在结构体数组`p`的相应位置。每次循环,函数会提示用户输入学生的姓名、性别、专业、班级、电话号码和宿舍号,并使用`scanf`函数读取用户的输入。接下来,函数将学生人数`n`存储到通过指针`len`传递的变量中,以便在后续的代码中可以使用。然后,函数会调用`regis`函数,将结构体数组中的学生信息写入文件中。
5.增加学生信息
void add(struct student *p, int *len) { int c = 1; // 定义变量c,用于存储用户的选择 // 循环添加学生信息,直到用户选择退出 while (c == 1) { int mylen = *len; // 将len的值赋给mylen struct student st; // 定义一个struct student类型的变量st,用于存储要添加的学生信息 printf("请输入要添加学生的信息:\n"); printf("姓名:"); scanf("%s", st.nam); printf("性别:"); scanf("%s", st.sex); printf("专业:"); scanf("%s", st.spec); printf("班级:"); scanf("%s", st.classid); printf("电话号码:"); scanf("%s", st.phone); printf("宿舍号:"); scanf("%s", st.bedroom); printf("\n"); p[mylen] = st; // 将学生信息添加到数组p的末尾 *len = mylen + 1; // 将len的值增加1 print_fun(p, *len); // 打印所有学生的信息 printf("\n"); printf("是否继续添加?输入:\n1.继续\n2.退出\n"); scanf("%d", &c); // 获取用户的选择 } regis(p, *len); // 将学生信息写入文件 }
函数首先定义变量c,用于存储用户的选择,然后通过循环添加学生信息,直到用户选择退出。循环内部,函数先将指针len指向的值存储到变量mylen中,然后定义一个新的结构体变量st,用来存储要添加的学生信息。接着,函数会提示用户输入要添加的学生信息,使用scanf函数获取用户的输入,并将输入的信息存储到结构体变量st中。然后,将st所存储的学生信息添加到原有学生信息的结构体数组p的末尾。另外,通过指针len传递的值增加1,以便在后续的代码中可以使用。
接下来,函数调用print_fun函数,将所有学生的信息打印出来以便修改验证。然后,函数会提示用户选择是否继续添加,如果用户选择退出,则跳出循环。最后,函数调用regis函数将更新后的学生信息写入文件中,以便下次使用时可以使用。
6.删除学生信息
void delete_student(struct student *p, int *len) { char nam[10]; // 定义一个字符数组,用于存储要删除的学生姓名 printf("请输入要删除的学生姓名: "); scanf("%s", nam); // 获取用户输入的学生姓名 int flag = 0; // 定义一个标志变量,用于记录是否找到匹配的学生姓名 // 循环查找学生姓名,并删除匹配的学生记录 for (int i = 0; i < *len; i++) { if (strcmp(p[i].nam, nam) == 0) { // 如果找到匹配的学生姓名 // 将后面的学生记录依次向前移动 for (int j = i; j < *len - 1; j++) { strcpy(p[j].nam, p[j + 1].nam); strcpy(p[j].sex, p[j + 1].sex); strcpy(p[j].spec, p[j + 1].spec); strcpy(p[j].classid, p[j + 1].classid); strcpy(p[j].phone, p[j + 1].phone); strcpy(p[j].bedroom, p[j + 1].bedroom); } (*len)--; // 更新学生记录数量 flag = 1; // 设置标志变量为1,表示找到了匹配的学生姓名 break; // 跳出循环 } } if (flag) { // 如果找到了匹配的学生姓名 printf("删除成功!\n"); regis(p, *len); // 将更新后的学生信息写入文件 } else { // 如果没有找到匹配的学生姓名 printf("学生姓名不存在!\n"); } }
函数首先定义一个字符数组`nam`,用于存储要删除的学生姓名,并提示用户输入要删除的学生姓名。然后使用`scanf`函数获取用户输入的学生姓名。接着,函数定义一个标志变量`flag`,用于记录是否找到匹配的学生姓名。
接下来,函数通过循环遍历已有的学生记录,从中查找匹配的学生姓名,并删除匹配的学生记录。当找到匹配的学生姓名时,函数使用一个内层循环将后面的学生记录依次向前移动,以覆盖被删除的学生记录。在移动学生记录后,通过`strcpy`函数将后面学生记录的属性值依次复制到当前学生记录中。同时,通过递减指针`len`所指向的值,以更新学生记录的数量。
如果成功删除了学生记录,则将标志变量`flag`设置为1表示找到了匹配的学生姓名,并跳出循环。否则,如果没有找到匹配的学生姓名,则标志变量`flag`保持为0。
最后,函数根据标志变量`flag`的值,判断是否成功删除了学生记录。如果成功删除了学生记录,则打印"删除成功!"的提示,并调用`regis`函数将更新后的学生信息写入文件。否则,如果没有找到匹配的学生姓名,则打印"学生姓名不存在!"的提示。
7.按姓名查询
void search_name(struct student *p, int len) { char nam1[100]; // 定义一个字符数组,用于存储要查询的学生姓名 printf("请输入要查询学生姓名:"); scanf("%s", nam1); // 获取用户输入的学生姓名 printf("姓名\t性别\t专业\t班级\t电话号码\t宿舍号\t\n"); int flag = 0; // 定义一个标志变量,用于记录是否找到匹配的学生姓名 // 循环查找学生姓名,并输出匹配的学生记录 for (int i = 0; i < len; i++) { if (strcmp(p[i].nam, nam1) == 0) { // 如果找到匹配的学生姓名 printf("%s\t%s\t%s\t%s\t%s\t\t%s\t\n", p[i].nam, p[i].sex, p[i].spec, p[i].classid, p[i].phone, p[i].bedroom); flag = 1; // 设置标志变量为1,表示找到了匹配的学生姓名 break; // 跳出循环 } } if (!flag) { // 如果没有找到匹配的学生姓名 printf("姓名输入有误!\n"); } }
函数首先定义一个字符数组`nam1`,用于存储要查询的学生姓名,并提示用户输入要查询的学生姓名。然后使用`scanf`函数获取用户输入的学生姓名。接着,函数打印一个表头,用于显示学生信息的各个属性。同时,函数定义一个标志变量`flag`,用于记录是否找到匹配的学生姓名。
接下来,函数通过循环遍历已有的学生记录,从中查找匹配的学生姓名,并输出匹配的学生记录。当找到匹配的学生姓名时,函数使用`printf`函数按照指定的格式输出匹配的学生的姓名、性别、专业、班级、电话号码和宿舍号。同时,将标志变量`flag`设置为1表示找到了匹配的学生姓名,并跳出循环。
最后,函数根据标志变量`flag`的值,判断是否成功找到了匹配的学生姓名。如果没有找到匹配的学生姓名,则打印"姓名输入有误!"的提示。
8.按班级查询
void search_class(struct student *p, int len) { char classid[10]; // 定义一个字符数组,用于存储要查询的班级 printf("请输入要查询的班级: "); scanf("%s", classid); // 获取用户输入的班级 printf("姓名\t性别\t专业\t班级\t电话号码\t宿舍号\t\n"); int flag = 0; // 定义一个标志变量,用于记录是否找到匹配的班级 // 循环查找班级,并输出匹配的学生记录 for (int i = 0; i < len; i++) { if (strcmp(p[i].classid, classid) == 0) { // 如果找到匹配的班级 printf("%s\t%s\t%s\t%s\t%s\t\t%s\t\n", p[i].nam, p[i].sex, p[i].spec, p[i].classid, p[i].phone, p[i].bedroom); flag = 1; // 设置标志变量为1,表示找到了匹配的班级 } } if (!flag) { // 如果没有找到匹配的班级 printf("没有找到该班级的学生信息!\n"); } }
函数首先定义一个字符数组`classid`,用于存储要查询的班级,并提示用户输入要查询的班级。然后使用`scanf`函数获取用户输入的班级。接着,函数打印一个表头,用于显示学生信息的各个属性。同时,函数定义一个标志变量`flag`,用于记录是否找到匹配的班级。
接下来,函数通过循环遍历已有的学生记录,从中查找匹配的班级,并输出匹配的学生记录。当找到匹配的班级时,函数使用`printf`函数按照指定的格式输出匹配的学生的姓名、性别、专业、班级、电话号码和宿舍号。同时,将标志变量`flag`设置为1表示找到了匹配的班级。
最后,函数根据标志变量`flag`的值,判断是否成功找到了匹配的班级。如果没有找到匹配的班级,则打印"没有找到该班级的学生信息!"的提示。
9.按专业查询
void search_specialty(struct student *p, int len) { char spec[20]; // 定义一个字符数组,用于存储要查询的专业 printf("请输入要查询的专业: "); scanf("%s", spec); // 获取用户输入的专业 printf("姓名\t性别\t专业\t班级\t电话号码\t宿舍号\t\n"); int flag = 0; // 定义一个标志变量,用于记录是否找到匹配的专业 // 循环查找专业,并输出匹配的学生记录 for (int i = 0; i < len; i++) { if (strcmp(p[i].spec, spec) == 0) { // 如果找到匹配的专业 printf("%s\t%s\t%s\t%s\t%s\t\t%s\t\n", p[i].nam, p[i].sex, p[i].spec, p[i].classid, p[i].phone, p[i].bedroom); flag = 1; // 设置标志变量为1,表示找到了匹配的专业 } } if (!flag) { // 如果没有找到匹配的专业 printf("没有找到该专业的学生信息!\n"); } }
函数首先定义一个字符数组`spec`,用于存储要查询的专业,并提示用户输入要查询的专业。然后使用`scanf`函数获取用户输入的专业。接着,函数打印一个表头,用于显示学生信息的各个属性。同时,函数定义一个标志变量`flag`,用于记录是否找到匹配的专业。
接下来,函数通过循环遍历已有的学生记录,从中查找匹配的专业,并输出匹配的学生记录。当找到匹配的专业时,函数使用`printf`函数按照指定的格式输出匹配的学生的姓名、性别、专业、班级、电话号码和宿舍号。同时,将标志变量`flag`设置为1表示找到了匹配的专业。
最后,函数根据标志变量`flag`的值,判断是否成功找到了匹配的专业。如果没有找到匹配的专业,则打印"没有找到该专业的学生信息!"的提示。
10.打印学生信息
void print_fun(struct student *p, int len) { printf("姓名\t性别\t专业\t班级\t电话号码\t宿舍号\t\n"); // 循环输出所有学生记录 for (int i = 0; i < len; i++) { printf("%s\t%s\t%s\t%s\t%s\t\t%s\t\n", p[i].nam, p[i].sex, p[i].spec, p[i].classid, p[i].phone, p[i].bedroom); } }
函数首先打印一个表头,用于显示学生信息的各个属性。接着,函数通过循环遍历已有的学生记录,并使用`printf`函数按照指定的格式输出每个学生的姓名、性别、专业、班级、电话号码和宿舍号。
11.完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> // 定义一个表示学生的结构体 struct student { char nam[10]; char sex[4]; char spec[20]; char classid[10]; char phone[15]; char bedroom[8]; }; // 函数声明 void createdata(struct student *stu, int *len); // 注册学生信息 void add(struct student *stu, int *len); // 增加学生信息 void delete_student(struct student *stu, int *len); // 删除学生信息 void search_name(struct student *stu, int len); // 按姓名查询 void search_class(struct student *stu, int len); // 按班级查询 void search_specialty(struct student *stu, int len); // 按专业查询 void print_fun(struct student *stu, int len); // 打印学生信息 // 主函数 int main() { int choice; struct student p[1024]; int len = 0; while (1) { printf("\n 新生报到信息注册系统\n\n"); printf("**********************************************************************\n"); printf("1. 注册学生信息\n"); printf("2. 增加学生信息\n"); printf("3. 删除学生信息\n"); printf("4. 按姓名查询\n"); printf("5. 按班级查询\n"); printf("6. 按专业查询\n"); printf("7. 打印学生信息\n"); printf("8. 退出系统\n"); printf("**********************************************************************\n"); printf("请输入选项:"); scanf("%d", &choice); switch (choice) { case 1: createdata(p, &len); break; case 2: add(p, &len); break; case 3: delete_student(p, &len); break; case 4: search_name(p, len); break; case 5: search_class(p, len); break; case 6: search_specialty(p, len); break; case 7: print_fun(p, len); break; case 8: printf("谢谢您的使用!\n\n"); exit(0); default: printf("输入有误!请重新输入。\n\n"); break; } } return 0; } //写入文件 void regis(struct student *p, int len) { FILE *fp; fp = fopen("student_info.txt", "w"); for (int i = 0; i < len; i++) { fprintf(fp, "%s %s %s %s %s %s\n", p[i].nam, p[i].sex, p[i].spec, p[i].classid, p[i].phone, p[i].bedroom); } fclose(fp); } // 读取文件 void read_data(struct student *p, int *len) { FILE *fp; fp = fopen("student_info.txt", "r"); if (fp == NULL) { printf("文件打开失败\n"); return; } while (fscanf(fp, "%s %s %s %s %s %s", p[*len].nam, p[*len].sex, p[*len].spec, p[*len].classid, p[*len].phone, p[*len].bedroom) == 6) { (*len)++; } fclose(fp); } // 注册学生信息 void createdata(struct student *p, int *len) { int n; printf("报到学生人数:"); scanf("%d", &n); printf("请输入学生信息:\n"); for (int i = 0; i < n; i++) { printf("学生%d:\n", i+1); printf("姓名:"); scanf("%s", p[i].nam); printf("性别:"); scanf("%s", p[i].sex); printf("专业:"); scanf("%s", p[i].spec); printf("班级:"); scanf("%s", p[i].classid); printf("电话号码:"); scanf("%s", p[i].phone); printf("宿舍号:"); scanf("%s", p[i].bedroom); printf("\n"); } *len = n; regis(p, n); } // 增加学生信息 void add(struct student *p, int *len) { int c = 1; while (c == 1) { int mylen = *len; struct student st; printf("请输入要添加学生的信息:\n"); printf("姓名:"); scanf("%s", st.nam); printf("性别:"); scanf("%s", st.sex); printf("专业:"); scanf("%s", st.spec); printf("班级:"); scanf("%s", st.classid); printf("电话号码:"); scanf("%s", st.phone); printf("宿舍号:"); scanf("%s", st.bedroom); printf("\n"); p[mylen] = st; *len = mylen + 1; print_fun(p, *len); printf("\n"); printf("是否继续添加?输入:\n1.继续\n2.退出\n"); scanf("%d", &c); } regis(p, *len); } // 删除学生信息 void delete_student(struct student *p, int *len) { char nam[10]; printf("请输入要删除的学生姓名: "); scanf("%s", nam); int flag = 0; for (int i = 0; i < *len; i++) { if (strcmp(p[i].nam, nam) == 0) { for (int j = i; j < *len - 1; j++) { strcpy(p[j].nam, p[j + 1].nam); strcpy(p[j].sex, p[j + 1].sex); strcpy(p[j].spec, p[j + 1].spec); strcpy(p[j].classid, p[j + 1].classid); strcpy(p[j].phone, p[j + 1].phone); strcpy(p[j].bedroom, p[j + 1].bedroom); } (*len)--; flag = 1; break; } } if (flag) { printf("删除成功!\n"); regis(p, *len); } else { printf("学生姓名不存在!\n"); } } // 按姓名查询 void search_name(struct student *p, int len) { char nam1[100]; printf("请输入要查询学生姓名:"); scanf("%s", nam1); printf("姓名\t性别\t专业\t班级\t电话号码\t宿舍号\t\n"); int flag = 0; for (int i = 0; i < len; i++) { if (strcmp(p[i].nam, nam1) == 0) { printf("%s\t%s\t%s\t%s\t%s\t\t%s\t\n", p[i].nam, p[i].sex, p[i].spec, p[i].classid, p[i].phone, p[i].bedroom); flag = 1; break; } } if (!flag) { printf("姓名输入有误!\n"); } } // 按班级查询 void search_class(struct student *p, int len) { char classid[10]; printf("请输入要查询的班级: "); scanf("%s", classid); printf("姓名\t性别\t专业\t班级\t电话号码\t宿舍号\t\n"); int flag = 0; for (int i = 0; i < len; i++) { if (strcmp(p[i].classid, classid) == 0) { printf("%s\t%s\t%s\t%s\t%s\t\t%s\t\n", p[i].nam, p[i].sex, p[i].spec, p[i].classid, p[i].phone, p[i].bedroom); flag = 1; } } if (!flag) { printf("没有找到该班级的学生信息!\n"); } } // 按专业查询 void search_specialty(struct student *p, int len) { char spec[20]; printf("请输入要查询的专业: "); scanf("%s", spec); printf("姓名\t性别\t专业\t班级\t电话号码\t宿舍号\t\n"); int flag = 0; for (int i = 0; i < len; i++) { if (strcmp(p[i].spec, spec) == 0) { printf("%s\t%s\t%s\t%s\t%s\t\t%s\t\n", p[i].nam, p[i].sex, p[i].spec, p[i].classid, p[i].phone, p[i].bedroom); flag = 1; } } if (!flag) { printf("没有找到该专业的学生信息!\n"); } } // 打印学生信息 void print_fun(struct student *p, int len) { printf("姓名\t性别\t专业\t班级\t电话号码\t宿舍号\t\n"); for (int i = 0; i < len; i++) { printf("%s\t%s\t%s\t%s\t%s\t\t%s\t\n", p[i].nam, p[i].sex, p[i].spec, p[i].classid, p[i].phone, p[i].bedroom); } }
运行截图:
说明:输入选项1后,填写报到学生人数最好不要超过10人,主要是一条一条数据输入得输半天。