函数结构代码中存储学生数据的访问逻辑与代码补全问题
C语言学生信息查询程序修复与疑问解答
一、修复现有代码,实现ID查询功能
现有代码存在核心逻辑缺陷:display函数未读取CSV文件内容就直接比较未初始化的结构体变量,无法匹配目标学生;同时输入处理存在截断和换行符干扰问题。修复后的完整代码如下:
#include <stdio.h> #include <string.h> struct Student { char id[5]; // 调整长度,容纳4位ID+字符串结束符 char name[8]; char course[5]; }; void populate() { FILE* fp = fopen("students.csv", "w"); if (!fp) { perror("Failed to open file for writing"); return; } struct Student s1 = {"1001", "John", "BSCS"}; fprintf(fp, "%s,%s,%s\n", s1.id, s1.name, s1.course); struct Student s2 = {"1002", "Bob", "BSIT"}; fprintf(fp, "%s,%s,%s\n", s2.id, s2.name, s2.course); struct Student s3 = {"1003", "Jane", "BSIT"}; fprintf(fp, "%s,%s,%s\n", s3.id, s3.name, s3.course); struct Student s4 = {"1004", "Karla", "BSIT"}; fprintf(fp, "%s,%s,%s\n", s4.id, s4.name, s4.course); struct Student s5 = {"1005", "Clarisse", "BSCS"}; fprintf(fp, "%s,%s,%s\n", s5.id, s5.name, s5.course); struct Student s6 = {"1006", "Peter", "BSCS"}; fprintf(fp, "%s,%s,%s\n", s6.id, s6.name, s6.course); struct Student s7 = {"1007", "Bob", "BSCS"}; fprintf(fp, "%s,%s,%s\n", s7.id, s7.name, s7.course); struct Student s8 = {"1008", "Stewie", "BSIT"}; fprintf(fp, "%s,%s,%s\n", s8.id, s8.name, s8.course); struct Student s9 = {"1009", "Bryan", "BSCS"}; fprintf(fp, "%s,%s,%s\n", s9.id, s9.name, s9.course); struct Student s10 = {"1010", "Kent", "BSIT"}; fprintf(fp, "%s,%s,%s\n", s10.id, s10.name, s10.course); fclose(fp); } void display(const char* target_id) { FILE* fp = fopen("students.csv", "r"); if (!fp) { perror("Failed to open file for reading"); return; } struct Student student; // 逐行解析CSV内容,匹配目标ID while (fscanf(fp, "%[^,],%[^,],%[^\n]\n", student.id, student.name, student.course) == 3) { if (strcmp(student.id, target_id) == 0) { printf("Student Id: %s\n", student.id); printf("Student Name: %s\n", student.name); printf("Course: %s\n", student.course); fclose(fp); return; } } printf("No student found with ID: %s\n", target_id); fclose(fp); } int main() { populate(); char id[5]; printf("Enter student_id: "); fgets(id, sizeof(id), stdin); // 去除fgets读取的换行符,避免干扰字符串比较 size_t len = strlen(id); if (len > 0 && id[len-1] == '\n') { id[len-1] = '\0'; } display(id); return 0; }
关键修复说明
- 调整数组长度:将ID数组改为
char id[5],确保容纳4位ID字符串和结束符\0 - 处理换行符:手动去除
fgets读取的换行符,避免ID匹配失败 - 完善文件读取逻辑:用
fscanf逐行解析CSV,遍历所有学生信息进行ID匹配 - 增加错误检查:对文件打开操作添加判断,避免空指针访问
二、能否直接访问Struct Student的s1至s10变量?
不能直接访问,原因如下:
s1到s10是populate函数内部的局部变量,仅在函数执行期间存在。函数执行完毕后,这些变量所在的栈内存会被系统回收,后续代码无法再访问其内存地址。- 示例代码中的写法
if(id == '1001'){printf("Student ID: %s\nStudent Name: %s\nCourse: %s", student s1);}本身存在语法错误,即便修正语法,也无法访问已销毁的局部变量。
替代方案
若想直接访问学生变量,可将其定义为全局数组:
// 全局数组存储所有学生信息 struct Student students[10] = { {"1001", "John", "BSCS"}, {"1002", "Bob", "BSIT"}, {"1003", "Jane", "BSIT"}, {"1004", "Karla", "BSIT"}, {"1005", "Clarisse", "BSCS"}, {"1006", "Peter", "BSCS"}, {"1007", "Bob", "BSCS"}, {"1008", "Stewie", "BSIT"}, {"1009", "Bryan", "BSCS"}, {"1010", "Kent", "BSIT"} }; void populate() { FILE* fp = fopen("students.csv", "w"); if (!fp) { perror("Failed to open file for writing"); return; } for (int i = 0; i < 10; i++) { fprintf(fp, "%s,%s,%s\n", students[i].id, students[i].name, students[i].course); } fclose(fp); } // 直接遍历全局数组匹配ID void display(const char* target_id) { for (int i = 0; i < 10; i++) { if (strcmp(students[i].id, target_id) == 0) { printf("Student Id: %s\n", students[i].id); printf("Student Name: %s\n", students[i].name); printf("Course: %s\n", students[i].course); return; } } printf("No student found with ID: %s\n", target_id); }
内容的提问来源于stack exchange,提问作者Reece
相关产品推荐
相关产品推荐

