C语言程序读取结构体文件时strcmp匹配失败,请求技术支持
问题排查:员工信息更新时strcmp匹配失败
核心问题原因
你的代码和文件存储格式完全不匹配,导致strcmp无法匹配目标名字:
- 代码中使用
fread/fwrite进行二进制读写,但实际employee.txt是纯文本格式。用二进制读取文本内容时,结构体emp.name会被填充一堆乱码,自然无法和输入的名字匹配。 - 额外隐患:
gets函数会读取输入末尾的换行符到缓冲区,即使格式正确,也可能导致名字末尾多一个换行符,引发匹配失败。
解决方案
根据你的现有文件格式,有两种修正方向:
方向1:将文件转为二进制存储(适合批量结构化数据)
先编写一个二进制写入程序,生成正确的二进制格式文件:
#include <stdio.h> #include <string.h> struct Employee { int id; char name[50]; float salary; }; int main() { FILE *file = fopen("employee.txt", "wb"); if (!file) { perror("Failed to open file"); return 1; } struct Employee emps[] = { {1, "aayush", 4000.0f}, {2, "aashish", 3000.0f} }; fwrite(emps, sizeof(struct Employee), 2, file); fclose(file); return 0; }
然后修改原更新程序,替换不安全的gets并处理换行符:
#include <stdio.h> #include <string.h> struct Employee { int id; char name[50]; float salary; }; int main() { FILE *file; char filename[] = "employee.txt"; int dataFound = 0; int recordno = 0; file = fopen(filename, "r+"); if (file == NULL) { printf("Could not open file %s for reading and writing.\n", filename); return 1; } char name[15]; printf("Enter the name of the employee to be updated: "); // 替换gets,用fgets读取并去掉末尾换行符 fgets(name, sizeof(name), stdin); size_t len = strlen(name); if (len > 0 && name[len-1] == '\n') { name[len-1] = '\0'; } struct Employee emp; while (fread(&emp, sizeof(emp), 1, file) == 1) { if (strcmp(emp.name, name) == 0) { dataFound = 1; printf("Enter the new details for employee %d:\n", emp.id); printf("Id: "); scanf("%d", &emp.id); printf("Salary: "); scanf("%f", &emp.salary); // 处理scanf遗留的换行符,避免影响后续读取 while (getchar() != '\n'); fseek(file, -sizeof(struct Employee), SEEK_CUR); if (fwrite(&emp, sizeof(struct Employee), 1, file) == 1) { printf("Employee details updated successfully.\n"); } recordno++; } } if (dataFound == 0) { printf("\nData not found\n"); } fclose(file); return 0; }
方向2:改为文本方式读写(适配现有文件格式)
直接解析文本文件的内容,用临时文件实现更新:
#include <stdio.h> #include <string.h> #include <stdlib.h> struct Employee { int id; char name[50]; float salary; }; int main() { FILE *file; char filename[] = "employee.txt"; int dataFound = 0; char name[15]; printf("Enter the name of the employee to be updated: "); fgets(name, sizeof(name), stdin); size_t len = strlen(name); if (len > 0 && name[len-1] == '\n') { name[len-1] = '\0'; } file = fopen(filename, "r"); if (!file) { printf("Could not open file %s for reading.\n", filename); return 1; } FILE *tempFile = fopen("temp.txt", "w"); if (!tempFile) { printf("Could not create temp file.\n"); fclose(file); return 1; } char line[100]; struct Employee emp; while (fgets(line, sizeof(line), file)) { if (sscanf(line, "Id : %d", &emp.id) == 1) { fgets(line, sizeof(line), file); sscanf(line, "Name : %s", emp.name); fgets(line, sizeof(line), file); sscanf(line, "Salary : %f", &emp.salary); if (strcmp(emp.name, name) == 0) { dataFound = 1; printf("Enter the new details for employee %d:\n", emp.id); printf("Id: "); scanf("%d", &emp.id); printf("Salary: "); scanf("%f", &emp.salary); while (getchar() != '\n'); } fprintf(tempFile, "Id : %d \n", emp.id); fprintf(tempFile, "Name : %s\n", emp.name); fprintf(tempFile, "Salary : %.1f \n", emp.salary); } else { fputs(line, tempFile); } } fclose(file); fclose(tempFile); remove(filename); rename("temp.txt", filename); dataFound ? printf("Employee details updated successfully.\n") : printf("\nData not found\n"); return 0; }
关键注意点
- 二进制读写与文本读写不能混用:
fread/fwrite对应二进制文件,fscanf/fprintf/fgets对应文本文件。 - 禁止使用
gets:该函数存在缓冲区溢出风险,必须用fgets替代,并手动处理输入末尾的换行符。
内容的提问来源于stack exchange,提问作者Aayush Pandey
相关产品推荐
相关产品推荐

