C语言解析日程TSV文件时首个课程链接被覆盖丢失问题求助
问题原因
你的代码存在两个核心错误共同导致了第一个链接丢失:
- 直接存储指向临时栈数组的指针:你代码中
link是strtok返回的指向栈数组line内部的指针,line会在每次fgets调用时被新读入的行完全覆盖,你没有把链接内容单独拷贝存储,所以之前存入sched数组的指针指向的内容会被后续读入的行不断替换。 - 课程块结束判断逻辑有缺陷:如果当前周的课程块后面没有空行、直接跟下一周的
[x]块,或者空行包含空白字符,你的空行判断不会触发,会继续读入下一周的[x]行并错误解析为课程行,atoi(strtok(line, ":"))解析[x]这类没有冒号的行时会返回0,hour-9得到负数,触发数组越界访问,刚好覆盖了你第一个课程的指针内容。
修复方案
- 存储链接时做深拷贝,把链接内容存到堆内存避免被覆盖,同时增加越界校验:
// 把 sched[hour - 9] = link; 替换为 if (hour >=9 && hour < 9 + CLASSES) { sched[hour -9] = strdup(link); // strdup会自动申请堆内存拷贝字符串内容 }
- 优化课程块结束逻辑,读到下一周的
[x]行时如果已经找到当前周,直接停止读取:
while(fgets(line, sizeof(line), file)) { if (line[0] == '[') { if (dayfound) { // 已读到当前周的所有内容,遇到下一周的头直接结束 break; } if (atoi(&line[1]) == current_day) { dayfound = 1; } continue; } // 原有空行判断保留,兼容有空行分隔的文件格式 if (dayfound && line[0] == '\n') { break; } // 原有课程行解析逻辑不变 if (dayfound) { hour = atoi(strtok(line, ":")); min = strtok(NULL, "\t"); sub = strtok(NULL, "\t"); link = strtok(NULL, "\t"); if (hour >=9 && hour < 9 + CLASSES) { sched[hour -9] = strdup(link); } } }
- 程序退出前记得遍历
sched数组释放strdup申请的内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者walidathome
相关产品推荐
相关产品推荐

