fscanf解析文件时指针未正常前进的问题排查
fscanf解析文件指针未前进的问题分析与修复
问题根源拆解
场景a:ESSID读取后需额外fscanf才能推进
你写的ESSID解析格式串是:
fscanf(filePointer, "ESSID: \"%[^\"]\"\n", data);
但文件里对应的行是ESSID:"Miguel 3"——ESSID:和"之间没有空格,而你格式串里多了一个空格。虽然fscanf会自动跳过格式串中的空白,但这个多余空格会引发隐性匹配问题:读取完"内的内容后,格式串末尾的\n虽能匹配换行,但后续读取Mode的代码会因指针位置异常失败。
更关键的是,你在ESSID读取后额外加的fscanf(filePointer, "%[A-Za-z]: %s\n", ignore, data);其实已经读取了Mode行,导致后续再调用fscanf(filePointer, "Mode:%s\n", data);时,指针已跳过Mode行,属于完全多余的错误操作。
场景b:Signal Level读取后指针停留在行内
你用这个格式串读取信号强度:
fscanf(filePointer, "%*[^-0123456789] %i\n", &n1);
文件里的行是Signal level=-83 dBm ,问题出在:
%*[^-0123456789]跳过Signal level=后,%i读取-83;- 格式串里的
\n只会匹配-83后面的空格,遇到dBm这个非空白字符就会停止匹配,导致指针停在d的位置,下一次循环的Cell匹配直接失败。
修复方案
场景a修复:移除多余代码,修正格式串
- 把ESSID的格式串改成和文件内容完全一致的形式,去掉
ESSID:后面的空格:fscanf(filePointer, "ESSID:\"%[^\"]\"\n", data); - 直接删掉读取ESSID后那行多余的
fscanf,直接读取Mode即可:fscanf(filePointer, "Mode:%s\n", data);
场景b修复:完全消耗信号强度行的剩余内容
修改信号强度的格式串,添加%*[^\n]跳过-83后面的所有字符直到换行:
fscanf(filePointer, "%*[^-0123456789] %i%*[^\n]\n", &n1);
这样%*[^\n]会吃掉 dBm,\n匹配换行,指针直接指向下一行的Cell开头,不需要再调用fgets。
额外优化建议
- 所有格式串尽量和文件行精确匹配,减少依赖fscanf自动跳过空白的隐性逻辑;
- 检查fscanf的返回值(比如读取整数时返回1,读取两个整数返回2),而不是只判断EOF,避免匹配失败时进入死循环;
- 对类似
Quality=27/70的行,用精确格式串替代模糊的跳过匹配:fscanf(filePointer, "Quality=%i/%i%*[^\n]\n", &n1, &n2);
修复后的核心代码片段
while (fscanf(filePointer, "Cell %i", &n1) == 1) { printf ("\n\nReading Record number %d\n",cell_pos+1); printf ("Cell %i \n", n1); cell[cell_pos].idCell=n1; // Address if (fscanf(filePointer, " Address: %s", data) != 1) break; strcpy(cell[cell_pos].MacAddress, data); printf("Address: -%s-\n", data); // ESSID if (fscanf(filePointer, " ESSID:\"%[^\"]\"", data) != 1) break; strcpy(cell[cell_pos].Essid, data); printf("ESSID: -%s-\n", data); // Mode if (fscanf(filePointer, " Mode:%s", data) != 1) break; strcpy(cell[cell_pos].Mode, data); printf("Mode: -%s-\n", data); // Channel if (fscanf(filePointer, " Channel:%i", &n1) != 1) break; cell[cell_pos].Channel= n1; printf("Channel %i \n", n1); // Encryption if (fscanf(filePointer, " Encryption key:%s", data) != 1) break; strcpy(cell[cell_pos].Encrypted, data); printf("Encryption: -%s-\n", data); // Quality if (fscanf(filePointer, " Quality=%i/%i", &n1,&n2) != 2) break; printf("Quality = %i/%i \n", n1,n2); cell[cell_pos].Quality1=n1; cell[cell_pos].Quality2=n2; // Frequency if (fscanf(filePointer, " Frequency: %f", &f1) != 1) break; cell[cell_pos].Frequency=f1; printf("Frequency: %f GHz\n", f1); // Signal Level if (fscanf(filePointer, " Signal level:%i%*[^\n]", &n1) != 1) break; cell[cell_pos].SignalLevel=n1; printf("Signal level= %i dBm\n", n1); cell_pos++; }
内容的提问来源于stack exchange,提问作者AndresG
相关产品推荐
相关产品推荐

