C语言图书馆管理系统ISBN重复校验功能突然失效问题
ISBN重复校验失效的核心问题定位
ab+文件模式的指针默认行为触发校验失效:ab+二进制追加模式打开文件时,系统会强制将文件读写偏移位置设置为文件末尾,此时后续执行的遍历全文件的fread循环从文件末尾开始读,根本无法读取到之前存储的任何图书记录,duplicate变量始终保持初始值0,校验逻辑完全走不到比对分支。前一晚功能正常大概率是测试临时修改过打开模式、或是文件指针未重置的偶然情况,今早运行时ab+的默认行为触发后就直接失效。- 结构读取的偏移量完全错配:磁盘上
bookdetails.bin存储的是完整的struct library结构(6个长度为100的字符数组,总大小600字节),代码中却用仅100字节大小的struct check作为读取单位,每次从当前偏移位置读100字节的内容。由于struct library中的isbn_no字段是最后一个元素,排在书名、出版社、作者、副本数、发行日期5个100字节字段之后,这种按100字节步长读取的方式,永远读不到真正存储的ISBN字段内容,strcmp比对自然无法匹配到重复项。 - 重复关闭文件指针的未定义行为:代码中当
duplicate == 1的分支内已经执行了fclose(bd),跳出分支后又无条件执行了一次fclose(bd),对同一个文件指针重复关闭会触发未定义行为,极端情况下会导致文件读写状态异常。 - 废弃函数的内存踩越风险:代码中使用的
gets()是C标准已明确废弃的接口,完全不校验输入长度,一旦用户输入的字符串超过数组预留的100字节空间,就会覆盖相邻内存区域的变量值,也可能造成校验逻辑随机失效。
修正关键操作:
- 打开文件后、执行ISBN校验循环前,调用
rewind(bd)将文件读写位置强制重置到文件头部,解决ab+模式默认指针在末尾的问题;- 校验环节按完整的
struct library大小读取每条磁盘记录,提取记录中的isbn_no字段做重复比对,替换原有的struct check读取逻辑;- 梳理文件关闭逻辑,保证同一个文件指针仅执行一次
fclose操作;- 将所有
gets()调用替换为带长度参数的fgets(),避免内存越界问题。
内容的提问来源于stack exchange,提问作者Waleed
相关产品推荐
相关产品推荐

