请求解析LoadNumbers函数功能、优化方案及if分支逻辑
解析LoadNumbers函数:功能、逻辑与优化
一、函数核心功能
原函数的意图是从文本文件中读取整数,存储到传入的int类型数组中,但实际代码存在逻辑bug,导致功能不符合预期——比如会错误丢弃读取到的0,还会给int数组添加无意义的'\0'(即0),甚至因为多余参数存在未定义行为的风险。
二、重点解析if判断逻辑
代码里的嵌套if是整个函数逻辑混乱的核心,拆解来看:
1. 第一个if语句
if (fscanf(textFile,"%*[^-+0-9]", &pNumberArray[i]) == EOF) break;
- 格式符
%*[^-+0-9]的作用:%*表示匹配到的内容不存储,[^-+0-9]表示匹配所有不是正负号、数字的字符,所以这个语句是想跳过当前位置到下一个有效数字(带正负号)之间的所有无效字符。 - 致命错误:
%*格式符不需要传入接收变量,后面的&pNumberArray[i]完全多余,属于无效参数,可能触发未定义行为。 - 退出逻辑:当这个fscanf返回EOF时,说明文件已经读完,直接跳出循环。
2. 第二个else if语句
else if (pNumberArray[i] != 0 ){++i; pNumberArray[i] = '\0';}
- 逻辑意图:如果刚读到的整数不是0,就把数组索引i自增,然后给新的数组位置赋值
'\0'。 - 问题点:
'\0'是字符串的终止符,int数组不需要这个标记,属于无意义操作;- 如果读到的数字是0,索引i不会自增,下一次循环会覆盖当前位置的0,直接丢弃这个有效数字;
- 最后一次读取非0数字后,i自增并赋值0,这个0会留在数组里,可能被误判为有效数字。
三、编码优化与效率提升
原代码不仅逻辑有问题,效率也偏低(每次循环调用两次fscanf,存在冗余IO),可以从以下方向优化:
1. 修复核心逻辑bug
- 去掉第一个fscanf里多余的
&pNumberArray[i]参数; - 删除给int数组赋值
'\0'的无效操作; - 调整索引自增逻辑:如果是要存储所有读取到的整数,不管是不是0,只要成功读取就自增索引;如果要过滤0,就明确添加判断。
2. 高效实现示例
void LoadNumbers(int* pNumberArray, FILE* textFile) { int i = 0; int readStatus; // 循环读取整数,直到文件结束 while ((readStatus = fscanf(textFile, "%d", &pNumberArray[i])) != EOF) { if (readStatus == 1) // 成功读取一个整数 { // 如果需要过滤0,取消下面的注释 // if (pNumberArray[i] != 0) ++i; } else // 遇到非数字无效字符,逐个跳过 { fscanf(textFile, "%*c"); } } }
- 效率提升点:
- 减少冗余的fscanf调用,只在读取失败时跳过无效字符,避免重复IO;
- 逻辑更清晰,消除了原代码中的未定义行为;
%d本身会自动跳过前导空白字符,无需额外处理,进一步减少不必要的操作。
内容的提问来源于stack exchange,提问作者grepawk
相关产品推荐
相关产品推荐

