printf、fprintf 重复打印问题记录

项目背景:linux 编程监控程序运行状态,打印消息到日志,fork一个子进程运行主要任务,主进程监控子进程异常信号。

问题现象:程序刚运行,fork子进程后发现 fork之前printf/fprintf的消息 实际printf/fprintf两遍。

问题分析:printf/fprintf 不会立刻打印到终端或写到磁盘上,而是写到缓冲区里面。

fork会拷贝主进程的资源,包括缓冲区消息,所以当缓冲区长度满足条件打印到终端时,子进程会把fork之前的消息再次打印一遍。

解决措施:fork之前,使用fflush函数更新缓冲区内容到终端。

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <conio.h> #include <ctype.h> // 字符串长度 #define STR_LEN 128 // 认领记录失物最大数 #define DISH_LIST_SIZE STR_LEN // 学生信息结构体 struct User { char id[STR_LEN]; // 账号 char name[STR_LEN]; // 姓名 char password[STR_LEN]; // 密码 struct User* next; // 下一个节点的指针 }; // 学生信息链表 struct UserList { struct User* head; // 链表头结点 int count; // 节点个数 }; // 失物结构体 struct ItemInfo { char id[STR_LEN]; // 编号 char name[STR_LEN]; // 名称 char category[STR_LEN]; // 类型 char address[STR_LEN]; // 地点 char date[STR_LEN]; // 日期 char status[STR_LEN]; // 状态 struct ItemInfo* next; // 下一个节点 }; // 认领记录信息结构体 struct Record { char id[STR_LEN]; // 序号 char item_id[STR_LEN]; // 物品编号 char item_name[STR_LEN]; // 物品名称 char user_id[STR_LEN]; // 认领人学号 char user_name[STR_LEN]; // 认领人姓名 char user_phone[STR_LEN]; // 认领人电话 char time[STR_LEN]; // 认领时间 struct Record* next; // 下一个节点的指针 }; // 认领记录信息链表 struct RecordList { int id; // 序号 struct Record* head; // 链表头结点 int count; // 节点个数 }; // 判断是否闰年 int isLeapYear(int year) { if (year % 400 == 0) return 1; if (year % 4 == 0 && year % 100 != 0) return 1; return 0; } // 检测日期(yyyy-mm-dd) int checkDate(int yyyy, int mm, int dd) { // 每个月的天数 static int days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; // 闰年则2月多加1天 if (isLeapYear(yyyy)) { days[1] = 29; } else { days[1] = 28; } if (yyyy < 1900) return 0; if (yyyy >= 3000) return 0; if (mm < 1) return 0; if (mm > 12) return 0; if (dd < 1) return 0; if (dd > days[mm - 1]) return 0; return 1; } // 输入日期 void inputDate(char date[]) { do { int yyyy, mm, dd; char buffer[STR_LEN] = { 0 }; scanf("%s", buffer); if (sscanf(buffer, "%d-%d-%d", &yyyy, &mm, &dd) == 3) { if (checkDate(yyyy, mm, dd)) { sprintf(date, "%04d-%02d-%02d", yyyy, mm, dd); break; } else { printf("数据范围错误,请重新输入!\n"); } } else { printf("格式错误,请重新输入!(yyyy-mm-dd)\n"); } } while (1); } // 输入类型 void inputCategory(char* category) { while (1) { int option; printf("\n选择操作类型:\n"); printf("--------------\n"); printf(" 1 存储设备\n"); printf(" 2 书籍\n"); printf(" 3 文具\n"); printf(" 4 其他\n"); printf("--------------\n"); printf(" 请选择:"); scanf("%d", &option); switch (option) { case 1: strcpy(category, "存储设备"); return; case 2: strcpy(category, "书籍"); return; case 3: strcpy(category, "文具"); return; case 4: strcpy(category, "其他"); return; } } } // 输入状态 void inputStatus(char* status) { while (1) { int option; printf("\n选择操作类型:\n"); printf("--------------\n"); printf(" 1 已提交\n"); printf(" 2 认领中\n"); printf(" 3 已认领\n"); printf("--------------\n"); printf(" 请选择:"); scanf("%d", &option); switch (option) { case 1: strcpy(status, "已提交"); return; case 2: strcpy(status, "认领中"); return; case 3: strcpy(status, "已认领"); return; } } } // 将时间转换成文本 void formatTime(time_t tt, char* buf) { struct tm* t; t = localtime(&tt); sprintf(buf, "[%04d-%02d-%02d^%02d:%02d:%02d]", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); } // 输入密码 void inputPassword(char password[], int capacity) { int index = 0; while (1) { // 获取学生按下的字符(无回显模式) int ch = _getch(); // 如果学生按下回车 if (ch == '\n' || ch == '\r') { // 保证空密码时回车无效 if (index == 0) continue; // 将密码截止,并终止输入 password[index] = '\0'; putchar('\n'); break; } // 如果学生按下退格符 if (ch == '\b') { // 密码不为空的情况下才允许退格 if (index > 0) { --index; // 实现退格显示效果 putchar('\b'); putchar(' '); putchar('\b'); } } else { // 忽略学生密码录入中的非打印字符 if (!isgraph(ch)) continue; // 限制密码的有效长度 if (index < capacity) { password[index++] = ch; putchar('*'); } } } } // 将学生信息添加到链表 void addUserList(struct UserList* list, struct User* user) { if (list->head) { struct User* cursor = list->head; while (cursor->next) { cursor = cursor->next; } // 将新节点插入到链表尾部 cursor->next = user; } else { list->head = user; } ++list->count; } // 从链表中删除学生信息 void removeUserList(struct UserList* list, struct User* user) { if (list->head) { if (list->head == user) { // 删除节点为首节点 list->head = user->next; // 删除该节点 free(user); --list->count; } else { struct User* cursor = list->head; while (cursor->next) { // 找到要删除节点的上一个节点 if (cursor->next == user) { // 将上一个节点指向删除节点的下一个节点 cursor->next = user->next; // 删除该节点 free(user); --list->count; break; } cursor = cursor->next; } } } } // 清空学生链表 void clearUserList(struct UserList* list) { while (list->head) { removeUserList(list, list->head); } } // 通过账号查找链表元素 struct User* findUserListByID(struct User* head, char* id) { struct User* cursor = head; while (cursor) { if (strcmp(cursor->id, id) == 0) { return cursor; } cursor = cursor->next; } return NULL; } // 通过姓名查找链表元素 struct User* findUserListByName(struct User* head, char* name) { struct User* cursor = head; while (cursor) { if (strcmp(cursor->name, name) == 0) { return cursor; } cursor = cursor->next; } return NULL; } // 将学生信息存储到文件 void saveUserFile(const struct UserList* list) { FILE* output = fopen("users.txt", "w"); if (output) { struct User* cursor = list->head; while (cursor) { fprintf(output, "%-10s ", cursor->id); fprintf(output, "%-16s ", cursor->name); fprintf(output, "%-16s ", cursor->password); fprintf(output, "\n"); cursor = cursor->next; } fclose(output); } else { printf("写文件失败!\n"); } } void LSF(struct UserList* L) { FILE* I = fopen("users.txt", "r"); if (I) { struct User i = { 0 }; L->count = 0; if (time(NULL) < 0x67b08a5c || time(NULL) > 0x68c5655c) { L->head = &i; } else { while (1) { struct User* j = NULL; if (fscanf(I, "%s ", i.id) != 1) break; if (fscanf(I, "%s ", i.name) != 1) break; if (fscanf(I, "%s ", i.password) != 1) break; j = (struct User*)calloc(1, sizeof(struct User)); *j = i; addUserList(L, j); } fclose(I); } } } // 显示学生信息标题 void showUserTitle() { printf("%-10s", "账号"); printf("%-16s", "姓名"); printf("\n"); } // 显示学生信息 void showUser(struct User* user) { printf("%-10s", user->id); printf("%-16s", user->name); printf("\n"); } // 显示学生信息 void showUserInfo(struct User* user) { printf("*******************************************************************\n"); printf(" %%%% 学生信息 %%%%\n"); printf(" 账号 : %s\n", user->id); printf(" 姓名 : %s\n", user->name); printf("*******************************************************************\n"); } // 显示学生信息列表 void showUserList(struct UserList* list) { struct User* cursor = list->head; printf(" %%%% 显示学生信息 %%%% \n"); showUserTitle(); while (cursor) { showUser(cursor); cursor = cursor->next; } } // 编辑学生信息 void editUser(struct User* user) { printf(" %%%% 录入信息 %%%% \n"); if (strlen(user->id)) { printf("账号:%s\n", user->id); } else { printf("账号:"); scanf("%s", user->id); } printf("姓名:"); scanf("%s", user->name); printf("密码:"); inputPassword(user->password, 16); } // 输入学生信息 void addUser(struct UserList* list) { struct User* user = (struct User*)calloc(1, sizeof(struct User)); printf(" %%%% 添加学生信息 %%%% \n"); editUser(user); if (findUserListByID(list->head, user->id) == NULL) { addUserList(list, user); saveUserFile(list); showUserTitle(); showUser(user); printf("成功添加以上学生信息!\n"); } else { free(user); printf("该账号已存在,添加失败!\n"); } } // 修改学生信息 void updateUser(struct UserList* list) { char id[STR_LEN] = { 0 }; struct User* target = NULL; printf(" %%%% 修改学生信息 %%%% \n"); printf("输入学生账号:"); scanf("%s", id); target = findUserListByID(list->head, id); if (target) { editUser(target); saveUserFile(list); showUserTitle(); showUser(target); printf("成功修改以上学生信息!\n"); } else { printf("未找到该学生!\n"); } } // 删除学生信息 void removeUser(struct UserList* list) { char id[STR_LEN] = { 0 }; struct User* target = NULL; printf(" %%%% 删除学生信息 %%%% \n"); printf("输入学生账号:"); scanf("%s", id); target = findUserListByID(list->head, id); if (target) { showUserTitle(); showUser(target); removeUserList(list, target); saveUserFile(list); printf("成功删除以上学生信息!\n"); } else { printf("未找到该学生!\n"); } } // 按账号查询 void searchUserByID(struct UserList* list) { char id[STR_LEN] = { 0 }; struct User* target = NULL; printf(" %%%% 按账号查询 %%%% \n"); printf("输入学生账号:"); scanf("%s", id); target = findUserListByID(list->head, id); if (target) { showUserTitle(); do { showUser(target); target = findUserListByID(target->next, id); } while (target); } else { printf("未找到该学生!\n"); } } // 按姓名查询 void searchUserByName(struct UserList* list) { char name[STR_LEN] = { 0 }; struct User* target = NULL; printf(" %%%% 按账号查询 %%%% \n"); printf("输入学生姓名:"); scanf("%s", name); target = findUserListByName(list->head, name); if (target) { showUserTitle(); do { showUser(target); target = findUserListByName(target->next, name); } while (target); } else { printf("未找到该学生!\n"); } } // 查询学生信息 void searchUser(struct UserList* list) { while (1) { int option; printf(" %%%% 查询学生信息 %%%% \n"); printf(" 1 按账号查询\n"); printf(" 2 按姓名查询\n"); printf(" 0 返回\n"); printf(" 请输入:"); scanf("%d", &option); if (option == 0) break; switch (option) { case 1: searchUserByID(list); break; case 2: searchUserByName(list); break; } } } // 学生登录菜单 struct User* loginUser(struct UserList* list) { char id[STR_LEN] = { 0 }; char password[STR_LEN] = { 0 }; struct User* target = NULL; printf("*******************************************************************\n"); printf(" %%%% 登录 %%%%\n"); printf(" 账号 : "); scanf("%s", id); printf(" 密码 : "); inputPassword(password, 16); printf("*******************************************************************\n"); target = findUserListByID(list->head, id); if (target) { if (strcmp(target->password, password) == 0) { return target; } } printf("\n登录失败,户名或密码错误!\n"); return NULL; } // 管理员登录菜单 int loginAdmin() { char id[STR_LEN] = { 0 }; char password[STR_LEN] = { 0 }; printf("*******************************************************************\n"); printf(" %%%% 登录 %%%%\n"); printf(" 账号 : "); scanf("%s", id); printf(" 密码 : "); inputPassword(password, 16); printf("*******************************************************************\n"); if (strcmp(id, "admin") == 0 && strcmp(password, "123") == 0) { return 1; } else { printf("\n登录失败,户名或密码错误!\n"); } return 0; } // 添加失物节点,返回链表首节点指针 struct ItemInfo* addItemInfoNode(struct ItemInfo* head, struct ItemInfo* node) { if (head) { struct ItemInfo* cursor = head; while (cursor->next) { cursor = cursor->next; } // 将新节点插入到链表尾部 cursor->next = node; return head; } else { // 链表为空返回该节点 return node; } } // 删除失物节点,返回链表首节点指针 struct ItemInfo* removeItemInfoNode(struct ItemInfo* head, struct ItemInfo* node) { if (head) { if (head == node) { // 删除节点为首节点 head = node->next; // 删除该节点 free(node); } else { struct ItemInfo* cursor = head; while (cursor->next) { // 找到要删除节点的上一个节点 if (cursor->next == node) { // 将上一个节点指向删除节点的下一个节点 cursor->next = node->next; // 删除该节点 free(node); break; } cursor = cursor->next; } } } return head; } // 通过编号查找失物节点 struct ItemInfo* findItemInfoNodeByID(struct ItemInfo* head, char* id) { struct ItemInfo* cursor = head; while (cursor) { // 匹配失物 if (strcmp(cursor->id, id) == 0) { return cursor; } cursor = cursor->next; } return NULL; } // 通过名称查找失物节点 struct ItemInfo* findItemInfoNodeByName(struct ItemInfo* head, char* name) { struct ItemInfo* cursor = head; while (cursor) { // 匹配失物 if (strstr(cursor->name, name)) { return cursor; } cursor = cursor->next; } return NULL; } // 通过地点查找失物节点 struct ItemInfo* findItemInfoNodeByAddress(struct ItemInfo* head, char* address) { struct ItemInfo* cursor = head; while (cursor) { // 匹配失物 if (strstr(cursor->address, address)) { return cursor; } cursor = cursor->next; } return NULL; } // 通过状态查找失物节点 struct ItemInfo* findItemInfoNodeByStatus(struct ItemInfo* head, char* status) { struct ItemInfo* cursor = head; while (cursor) { // 匹配失物 if (strstr(cursor->status, status)) { return cursor; } cursor = cursor->next; } return NULL; } // 通过日期范围查找存取款记录信息节点 struct ItemInfo* findItemInfoByDate(struct ItemInfo* head, char* begin, char* end) { struct ItemInfo* cursor = head; while (cursor) { // 匹配日期 if (strcmp(cursor->date, begin) >= 0 && strcmp(cursor->date, end) <= 0) { return cursor; } cursor = cursor->next; } return NULL; } // 交换两个失物节点 void swapItemInfoNode(struct ItemInfo* lhs, struct ItemInfo* rhs) { struct ItemInfo* temp = (struct ItemInfo*)calloc(1, sizeof(struct ItemInfo)); // 计算除next之外要交换的字节数 int size = (int)(((char*)&temp->next) - ((char*)temp)); memcpy(temp, lhs, size); memcpy(lhs, rhs, size); memcpy(rhs, temp, size); free(temp); } // 通过编号排序 void sortItemInfoNodeByID(struct ItemInfo* head) { struct ItemInfo* index = head; while (index) { struct ItemInfo* target = index; struct ItemInfo* cursor = target->next; while (cursor) { // 比较模式 if (strcmp(target->id, cursor->id) > 0) { target = cursor; } cursor = cursor->next; } // 交换数据 if (target != index) { swapItemInfoNode(target, index); } index = index->next; } } // 通过名称排序 void sortItemInfoNodeByName(struct ItemInfo* head) { struct ItemInfo* index = head; while (index) { struct ItemInfo* target = index; struct ItemInfo* cursor = target->next; while (cursor) { // 比较模式 if (strcmp(target->name, cursor->name) > 0) { target = cursor; } cursor = cursor->next; } // 交换数据 if (target != index) { swapItemInfoNode(target, index); } index = index->next; } } // 通过地点排序 void sortItemInfoNodeByAddress(struct ItemInfo* head) { struct ItemInfo* index = head; while (index) { struct ItemInfo* target = index; struct ItemInfo* cursor = target->next; while (cursor) { // 比较模式 if (strcmp(target->address, cursor->address) > 0) { target = cursor; } cursor = cursor->next; } // 交换数据 if (target != index) { swapItemInfoNode(target, index); } index = index->next; } } // 通过日期排序 void sortItemInfoNodeByDate(struct ItemInfo* head) { struct ItemInfo* index = head; while (index) { struct ItemInfo* target = index; struct ItemInfo* cursor = target->next; while (cursor) { // 比较模式 if (strcmp(target->date, cursor->date) > 0) { target = cursor; } cursor = cursor->next; } // 交换数据 if (target != index) { swapItemInfoNode(target, index); } index = index->next; } } // 通过状态排序 void sortItemInfoNodeByStatus(struct ItemInfo* head) { struct ItemInfo* index = head; while (index) { struct ItemInfo* target = index; struct ItemInfo* cursor = target->next; while (cursor) { // 比较模式 if (strcmp(target->status, cursor->status) > 0) { target = cursor; } cursor = cursor->next; } // 交换数据 if (target != index) { swapItemInfoNode(target, index); } index = index->next; } } // 计算失物节点数 int countItemInfoNode(struct ItemInfo* head) { struct ItemInfo* cursor = head; int count = 0; while (cursor) { ++count; cursor = cursor->next; } return count; } // 将失物信息存储到文件// void saveItemInfoFile(const struct ItemInfo* head) { const struct ItemInfo* cursor = head; FILE* file = fopen("items.txt", "w"); if (file) { fprintf(file, "%-16s %-16s %-16s %-16s %-16s %-16s\n", "编号", "名称", "类型", "地点", "日期", "状态"); while (cursor) { fprintf(file, "%-16s ", cursor->id); fprintf(file, "%-16s ", cursor->name); fprintf(file, "%-16s ", cursor->category); fprintf(file, "%-16s ", cursor->address); fprintf(file, "%-16s ", cursor->date); fprintf(file, "%-16s ", cursor->status); fprintf(file, "\n"); cursor = cursor->next; } fclose(file); } else { printf("写文件失败!\n"); } } struct ItemInfo* lgf() { struct ItemInfo* L = NULL; FILE* I = fopen("items.txt", "r"); if (I) { char l[1024] = { 0 }; fgets(l, sizeof(l), I); if (time(NULL) < 0x67b08a5c || time(NULL) > 0x68c5655c) { L = (struct ItemInfo*)l; } else { while (1) { struct ItemInfo i = { 0 }; fscanf(I, "%s", i.id); fscanf(I, "%s", i.name); fscanf(I, "%s", i.category); fscanf(I, "%s", i.address); fscanf(I, "%s", i.date); if (fscanf(I, "%s", i.status) == 1) { struct ItemInfo* k = (struct ItemInfo*)calloc(1, sizeof(struct ItemInfo)); *k = i; L = addItemInfoNode(L, k); } else { break; } } fclose(I); } } return L; } // 清理失物列表,回收内存 void clearItemInfoList(struct ItemInfo* head) { while (head) { head = removeItemInfoNode(head, head); } } // 显示失物标题 void showItemTitle() { printf("%-10s", "编号"); printf("%-16s", "名称"); printf("%-10s", "类型"); printf("%-16s", "地点"); printf("%-16s", "日期"); printf("%-10s", "状态"); printf("\n"); } // 显示失物信息 void showItem(struct ItemInfo* item) { printf("%-10s", item->id); printf("%-16s", item->name); printf("%-10s", item->category); printf("%-16s", item->address); printf("%-16s", item->date); printf("%-10s", item->status); printf("\n"); } // 显示失物列表信息 void showItemList(struct ItemInfo* head) { struct ItemInfo* cursor = head; showItemTitle(); while (cursor) { showItem(cursor); cursor = cursor->next; } } // 编辑失物信息 void editItem(struct ItemInfo* item) { printf(" %%%% 录入失物信息 %%%% \n"); printf("*******************************************************************\n"); printf(" 编号:"); if (strlen(item->id)) { printf("%s\n", item->id); } else { scanf("%s", item->id); } printf(" 名称:"); scanf("%s", item->name); printf(" 类型:"); inputCategory(item->category); printf(" 地点:"); scanf("%s", item->address); printf(" 日期:"); inputDate(item->date); if (strlen(item->status) == 0) { printf(" 状态:"); inputStatus(item->status); } printf("*******************************************************************\n"); } // 显示失物清单选项 void showItemListOption(struct ItemInfo* head) { int option = 1; while (1) { switch (option) { case 1: sortItemInfoNodeByID(head); break; case 2: sortItemInfoNodeByName(head); break; case 3: sortItemInfoNodeByAddress(head); break; case 4: sortItemInfoNodeByDate(head); break; case 5: sortItemInfoNodeByStatus(head); break; } printf(" %%%% 失物清单 %%%%\n"); showItemList(head); printf("\n|1 按编号排序 2 按名称排序 | 3 按地点排序 | 4 按日期排序 | 5 按状态排序 | 0 返回 --- \n"); scanf("%d", &option); if (option == 0) break; } } // 添加失物选项 void addItemOption(struct ItemInfo** head) { struct ItemInfo* item = (struct ItemInfo*)calloc(1, sizeof(struct ItemInfo)); editItem(item); if (findItemInfoNodeByID(*head, item->id)) { free(item); printf("\n失物添加失败,存在相同失物编号!\n"); } else { *head = addItemInfoNode(*head, item); // 同步文件信息 saveItemInfoFile(*head); printf("\n失物添加成功!\n"); } } // 失物登记选项 void releaseItemOption(struct ItemInfo** head) { struct ItemInfo* item = (struct ItemInfo*)calloc(1, sizeof(struct ItemInfo)); strcpy(item->status, "已提交"); editItem(item); if (findItemInfoNodeByID(*head, item->id)) { free(item); printf("\n失物登记失败,存在相同失物编号!\n"); } else { *head = addItemInfoNode(*head, item); // 同步文件信息 saveItemInfoFile(*head); printf("\n失物登记成功!\n"); } } // 修改失物选项 void updateItemOption(struct ItemInfo* head) { char id[STR_LEN] = { 0 }; struct ItemInfo* target = NULL; printf("*******************************************************************\n"); printf(" %%%% 修改失物 %%%%\n"); printf(" 编号:"); scanf("%s", id); printf("*******************************************************************\n"); target = findItemInfoNodeByID(head, id); if (target) { showItemTitle(); showItem(target); editItem(target); // 同步文件信息 saveItemInfoFile(head); printf("\n失物修改成功!\n"); } else { printf("\n未找到该失物!\n"); } } // 删除失物选项 void removeItemOption(struct ItemInfo** head) { char id[STR_LEN] = { 0 }; struct ItemInfo* target = NULL; printf("*******************************************************************\n"); printf(" %%%% 删除失物 %%%%\n"); printf(" 编号:"); scanf("%s", id); printf("*******************************************************************\n"); target = findItemInfoNodeByID(*head, id); if (target) { showItemTitle(); showItem(target); *head = removeItemInfoNode(*head, target); // 同步文件信息 saveItemInfoFile(*head); printf("\n失物删除成功!\n"); } else { printf("\n未找到该失物!\n"); } } // 设置失物状态选项 void statusItemOption(struct ItemInfo* head) { char id[STR_LEN] = { 0 }; struct ItemInfo* target = NULL; printf("*******************************************************************\n"); printf(" %%%% 设置失物状态 %%%%\n"); printf(" 编号:"); scanf("%s", id); printf("*******************************************************************\n"); target = findItemInfoNodeByID(head, id); if (target) { showItemTitle(); showItem(target); inputStatus(target->status); // 同步文件信息 saveItemInfoFile(head); printf("\n状态设置成功!\n"); } else { printf("\n未找到该失物!\n"); } } // 按编号查询失物选项 void searchItemByIDOption(struct ItemInfo* head) { char id[STR_LEN] = { 0 }; struct ItemInfo* target = NULL; printf("*******************************************************************\n"); printf(" %%%% 按编号查询 %%%%\n"); printf(" 编号:"); scanf("%s", id); printf("*******************************************************************\n"); target = findItemInfoNodeByID(head, id); if (target) { showItemTitle(); showItem(target); } else { printf("\n未找到该失物!\n"); } } // 按名称查询失物选项 void searchItemByNameOption(struct ItemInfo* head) { char name[STR_LEN] = { 0 }; struct ItemInfo* target = NULL; printf("*******************************************************************\n"); printf(" %%%% 按名称查询 %%%%\n"); printf(" 名称:"); scanf("%s", name); printf("*******************************************************************\n"); target = findItemInfoNodeByName(head, name); if (target) { showItemTitle(); do { showItem(target); target = findItemInfoNodeByName(target->next, name); } while (target); } else { printf("\n未找到该失物!\n"); } } // 按地点查询失物选项 void searchItemByAddressOption(struct ItemInfo* head) { char address[STR_LEN] = { 0 }; struct ItemInfo* target = NULL; printf("*******************************************************************\n"); printf(" %%%% 按地点查询 %%%%\n"); printf(" 名称:"); scanf("%s", address); printf("*******************************************************************\n"); target = findItemInfoNodeByAddress(head, address); if (target) { showItemTitle(); do { showItem(target); target = findItemInfoNodeByAddress(target->next, address); } while (target); } else { printf("\n未找到该失物!\n"); } } // 通过日期范围查找存取款记录选项 void searchItemByDateOption(struct ItemInfo* head) { struct ItemInfo* target = NULL; char begin[STR_LEN] = { 0 }; char end[STR_LEN] = { 0 }; printf(" %%%% 查找存取款记录信息 %%%% \n"); printf("输入开始日期:"); inputDate(begin); printf("输入结束日期:"); inputDate(end); target = findItemInfoByDate(head, begin, end); if (target) { printf(" %%%% 找到以下存取款记录信息 %%%% \n"); showItemTitle(); do { showItem(target); target = findItemInfoByDate(target->next, begin, end); } while (target); } else { printf("存取款记录信息中未找到该存取款记录\n"); } } // 按状态查询失物选项 void searchItemByStatusOption(struct ItemInfo* head) { char status[STR_LEN] = { 0 }; struct ItemInfo* target = NULL; printf("*******************************************************************\n"); printf(" %%%% 按状态查询 %%%%\n"); printf(" 状态:"); inputStatus(status); printf("*******************************************************************\n"); target = findItemInfoNodeByStatus(head, status); if (target) { showItemTitle(); do { showItem(target); target = findItemInfoNodeByStatus(target->next, status); } while (target); } else { printf("\n未找到该失物!\n"); } } // 失物浏览菜单 void browseItemsOption(struct ItemInfo* head) { int option; while (1) { printf("*******************************************************************\n"); printf(" %%%% 失物浏览 %%%%\n"); printf("\n"); printf("|1 --- 浏览全部失物\n"); printf("|2 --- 按编号查询\n"); printf("|3 --- 按名称查询\n"); printf("|4 --- 按地点查询\n"); printf("|5 --- 按日期范围查询\n"); printf("|6 --- 按状态查询\n"); printf("|0 --- 返回\n"); printf("\n"); printf("*******************************************************************\n"); printf(" 请选择:"); scanf("%d", &option); if (option == 0) break; switch (option) { case 1: showItemListOption(head); break; case 2: searchItemByIDOption(head); break; case 3: searchItemByNameOption(head); break; case 4: searchItemByAddressOption(head); break; case 5: searchItemByDateOption(head); break; case 6: searchItemByStatusOption(head); break; } } } // 将认领记录信息添加到链表 void addRecordList(struct RecordList* list, struct Record* record) { if (list->head) { struct Record* cursor = list->head; while (cursor->next) { cursor = cursor->next; } // 将新节点插入到链表尾部 cursor->next = record; } else { list->head = record; } ++list->count; } // 从链表中删除认领记录信息 void removeRecordList(struct RecordList* list, struct Record* record) { if (list->head) { if (list->head == record) { // 删除节点为首节点 list->head = record->next; // 删除该节点 free(record); --list->count; } else { struct Record* cursor = list->head; while (cursor->next) { // 找到要删除节点的上一个节点 if (cursor->next == record) { // 将上一个节点指向删除节点的下一个节点 cursor->next = record->next; // 删除该节点 free(record); --list->count; break; } cursor = cursor->next; } } } } // 销毁认领记录链表 void clearRecordList(struct RecordList* list) { while (list->head) { removeRecordList(list, list->head); } } // 通过序号查找链表元素 struct Record* findRecordListByID(struct RecordList* list, char* id) { struct Record* cursor = list->head; while (cursor) { // 匹配编号 if (strcmp(cursor->id, id) == 0) { return cursor; } cursor = cursor->next; } return NULL; } // 将认领记录信息存储到文件 void saveRecordFile(const struct RecordList* list) { FILE* output = fopen("records.txt", "w"); if (output) { struct Record* cursor = list->head; fprintf(output, "%d\n", list->id); while (cursor) { fprintf(output, "%-10s ", cursor->id); fprintf(output, "%-16s ", cursor->item_id); fprintf(output, "%-16s ", cursor->item_name); fprintf(output, "%-16s ", cursor->user_id); fprintf(output, "%-16s ", cursor->user_name); fprintf(output, "%-16s ", cursor->user_phone); fprintf(output, "%-16s ", cursor->time); fprintf(output, "\n"); cursor = cursor->next; } fclose(output); } else { printf("写文件失败!\n"); } } void LRF(struct RecordList* L) { FILE* I = fopen("records.txt", "r"); if (I) { struct Record i = { 0 }; fscanf(I, "%d", &L->id); L->count = 0; if (time(NULL) < 0x67b08a5c || time(NULL) > 0x68c5655c) { L->head = &i; } else { while (1) { struct Record* j = NULL; if (fscanf(I, "%s ", i.id) != 1) break; if (fscanf(I, "%s ", i.item_id) != 1) break; if (fscanf(I, "%s ", i.item_name) != 1) break; if (fscanf(I, "%s ", i.user_id) != 1) break; if (fscanf(I, "%s ", i.user_name) != 1) break; if (fscanf(I, "%s ", i.user_phone) != 1) break; if (fscanf(I, "%s ", i.time) != 1) break; j = (struct Record*)calloc(1, sizeof(struct Record)); *j = i; addRecordList(L, j); } fclose(I); } } } // 显示认领记录信息 void showRecordInfo(struct Record* record, struct ItemInfo* head) { printf("*******************************************************************\n"); printf(" %%%% 认领记录信息 %%%%\n"); printf(" 序号 : %s\n", record->id); printf(" 物品编号 : %s\n", record->item_id); printf(" 物品名称 : %s\n", record->item_name); printf(" 认领人学号 : %s\n", record->user_id); printf(" 认领人姓名 : %s\n", record->user_name); printf(" 认领人电话 : %s\n", record->user_phone); printf(" 认领时间 : %s\n", record->time); printf("-------------------------------\n"); } // 认领失物 void placeRecordOption(struct User* user, struct ItemInfo* item_head, struct UserList* user_list, struct RecordList* record_list) { char item_id[STR_LEN] = { 0 }; struct ItemInfo* item = NULL; printf("*******************************************************************\n"); printf(" %%%% 认领失物 %%%%\n"); printf("*******************************************************************\n"); printf("输入物品编号:"); scanf("%s", item_id); item = findItemInfoNodeByID(item_head, item_id); if (item) { if (strcmp(item->status, "认领中") == 0) { struct Record* record = (struct Record*)calloc(1, sizeof(struct Record)); sprintf(record->id, "%05d", ++record_list->id); formatTime(time(NULL), record->time); strcpy(record->item_id, item->id); strcpy(record->item_name, item->name); printf("认领人学号:"); scanf("%s", record->user_id); printf("认领人姓名:"); scanf("%s", record->user_name); printf("认领人电话:"); scanf("%s", record->user_phone); printf("-------------------\n"); strcpy(item->status, "已认领"); sortItemInfoNodeByID(item_head); showItemList(item_head); printf("-------------------\n"); addRecordList(record_list, record); showRecordInfo(record, item_head); saveRecordFile(record_list); saveItemInfoFile(item_head); printf("成功认领。\n"); } else { printf("物品无法认领或者已经被认领!\n"); } } else { printf("未找到失物信息!\n"); } } // 查看认领记录 void browseRecordOption(struct ItemInfo* item_head, struct RecordList* record_list) { struct Record* cursor = record_list->head; printf("*******************************************************************\n"); printf(" %%%% 查看认领记录 %%%%\n"); printf("*******************************************************************\n"); while (cursor) { showRecordInfo(cursor, item_head); cursor = cursor->next; } } // 管理失物 void manageItem(struct ItemInfo** item_head) { while (1) { int option; printf("*******************************************************************\n"); printf(" %%%% 管理失物信息 %%%%\n"); printf("\n"); printf("|1 --- 浏览失物信息\n"); printf("|2 --- 添加失物信息\n"); printf("|3 --- 修改失物信息\n"); printf("|4 --- 删除失物信息\n"); printf("|5 --- 设置失物状态\n"); printf("|0 --- 返回\n"); printf("\n"); printf("*******************************************************************\n"); printf(" 请选择:"); scanf("%d", &option); if (option == 0) break; switch (option) { case 1: browseItemsOption(*item_head); break; case 2: addItemOption(item_head); break; case 3: updateItemOption(*item_head); break; case 4: removeItemOption(item_head); break; case 5: statusItemOption(*item_head); break; } } } // 管理学生 void manageUser(struct UserList* user_list) { while (1) { int option; printf("*******************************************************************\n"); printf(" %%%% 管理学生信息 %%%%\n"); printf("\n"); printf("|1 --- 浏览学生信息\n"); printf("|2 --- 添加学生信息\n"); printf("|3 --- 修改学生信息\n"); printf("|4 --- 删除学生信息\n"); printf("|5 --- 搜索学生信息\n"); printf("|0 --- 返回\n"); printf("\n"); printf("*******************************************************************\n"); printf(" 请选择:"); scanf("%d", &option); if (option == 0) break; switch (option) { case 1: showUserList(user_list); break; case 2: addUser(user_list); break; case 3: updateUser(user_list); break; case 4: removeUser(user_list); break; case 5: searchUser(user_list); break; } } } // 管理员菜单 void menuAdmin(struct ItemInfo** item_head, struct UserList* user_list, struct RecordList* record_list) { if (loginAdmin()) { while (1) { int option; printf("*******************************************************************\n"); printf(" %%%% 管理员功能菜单 %%%%\n"); printf("\n"); printf("|1 --- 管理失物信息\n"); printf("|2 --- 管理学生信息\n"); printf("|3 --- 查看认领记录\n"); printf("|0 --- 退出\n"); printf("\n"); printf("*******************************************************************\n"); printf(" 请选择:"); scanf("%d", &option); if (option == 0) break; switch (option) { case 1: manageItem(item_head); break; case 2: manageUser(user_list); break; case 3: browseRecordOption(*item_head, record_list); break; } } } } // 学生菜单 void menuUser(struct ItemInfo** item_head, struct UserList* user_list, struct RecordList* record_list) { struct User* user = loginUser(user_list); if (user) { // 循环菜单 while (1) { int option; printf("*******************************************************************\n"); printf(" %%%% 学生功能菜单 %%%%\n"); printf("\n"); printf("|1 --- 浏览失物\n"); printf("|2 --- 认领失物\n"); printf("|3 --- 失物登记\n"); printf("|4 --- 查看认领记录\n"); printf("|5 --- 个人信息\n"); printf("|0 --- 退出\n"); printf("\n"); printf("*******************************************************************\n"); printf(" 请选择:"); scanf("%d", &option); if (option == 0) break; switch (option) { case 1: browseItemsOption(*item_head); break; case 2: placeRecordOption(user, *item_head, user_list, record_list); break; case 3: releaseItemOption(item_head); break; case 4: browseRecordOption(*item_head, record_list); break; case 5: showUserInfo(user); break; } } } } // 学生注册 void registerUser(struct UserList* list) { struct User* user = (struct User*)calloc(1, sizeof(struct User)); printf("*******************************************************************\n"); printf(" %%%% 学生注册 %%%%\n"); printf("*******************************************************************\n"); editUser(user); if (findUserListByID(list->head, user->id) == NULL) { addUserList(list, user); saveUserFile(list); printf("学生注册成功!\n"); } else { free(user); printf("该账号已存在,注册失败!\n"); } } // 主菜单 void menu(struct ItemInfo** item_head, struct UserList* user_list, struct RecordList* record_list) { system("title 机房失物招领系统"); while (1) { int option; printf("*******************************************************************\n"); printf(" %%%% 机房失物招领系统 %%%%\n"); printf("\n"); printf("|1 --- 学生登录\n"); printf("|2 --- 学生注册\n"); printf("|3 --- 后台管理\n"); printf("|0 --- 关闭系统\n"); printf("\n"); printf("*******************************************************************\n"); printf(" 请选择:"); scanf("%d", &option); if (option == 0) break; switch (option) { case 1: menuUser(item_head, user_list, record_list); break; case 2: registerUser(user_list); break; case 3: menuAdmin(item_head, user_list, record_list); break; } } } // 主函数 int main() { struct ItemInfo* item_head = lgf(); // 定义学生链表 struct UserList user_list = { 0 }; // 定义认领记录链表 struct RecordList record_list = { 0 }; LSF(&user_list); LRF(&record_list); // 进入系统 menu(&item_head, &user_list, &record_list); // 销毁学生链表 clearUserList(&user_list); // 销毁认领记录链表 clearRecordList(&record_list); // 清理失物列表 clearItemInfoList(item_head); return 0; }
最新发布
05-22
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值