最近在做一个wifiap设置的接口,用户首先获取到当前wifi 热点的ssid 和pwd,然后修改,保存。

获取信息的时候是fopen对应的hostapd.conf文件,逐行读取,查找匹配的参数。

修改的时候则是逐行读取当前hostapd.conf文件,逐行写到新的临时配置文件里面,如果匹配到ssid或者pwd则修改成新的值再写到新文件里面。

最后将新的临时配置文件rename成hostapd.conf。

测试的时修改完后,cat出hostapd.conf的检查发现最后一行总是重复两遍。

虽然不影响整体功能,但是非常出乎意料,超出预期设计的效果。

读取更新的代码逻辑大致如下

                                        while (!feof(srcF))
{
//get line data
fgets(tmp, sizeof(tmp), srcF);
f = tmp;
LOGD("get %s",f); //clear space in the head
while(' ' == *f || '\n' == *f || '\r' == *f)
f++;
if('\0' == *f)
continue;
//if the comments copy directly
if('#' == *f)
{
LOGD("get comments %s", f);
fputs(f, dstF);
continue;
}
p = strstr(f, WIFI_SSID);
//we must makesure it is start with my str
if(p == f)
{
//replace new ssid name
p += strlen(WIFI_SSID);
sprintf(p,"%s\n", ssid);
LOGD("replace new ssid %s",f);
fputs(f, dstF);
continue;
} p = strstr(f, WIFI_PW);
//we must makesure it is start with my str
if(p == f)
{
//replace new password
p += strlen(WIFI_PW);
sprintf(p,"%s\n", pw);
LOGD("replace new pwd%s",f);
fputs(f, dstF);
continue;
}
else
fputs(f, dstF);
LOGD("copy %s",f);

大概看一下总体的循环逻辑是没错

【判断是否到了文件结束-->读取一行内容-->将读取的内容写到新的文件中】

但是仔细查条件检查和返回值的判断,还是发现忽略了一些细节。

1、读完了最后一行还没读到EOF,需要下一次读取才到EOF。

2、没有对fgets返回值进行判断,最后一次读完再去读取的时候会返回NULL。

3、没有对读取数据的tmp buf进行清空处理。

事实上最后一次没读到东西,只是tmp里面的数据是上一次读取没有清空的,所以造成了重复读取的错觉。

解决方法如下:

1、判断fgets返回值,如果是NULL则continue返回去继续判断eof

 while (!feof(srcF))
{
//get line data
if(NULL == fgets(tmp, sizeof(tmp), srcF))
continue;
...........
}

2、先读取后判断eof

 while (1)
{
//get line data
fgets(tmp, sizeof(tmp), srcF);
if(feof(srcF))
break;
................ }

以上经过验证ok。

另外最好在每次使用buf前都进行一次memset,清空缓存。

有关fgetc配合feof逐行读取文件最后一行读取两遍的错觉?的更多相关文章

  1. PureBasic 读取文件中一行的两个数据例子

    , "Test1.txt") ; if the file could be read, we continue... , "Test2.txt") ) = ; ...

  2. shell读取文件每一行的方式

    1.使用read命令读取一行数据 while read myline do echo "LINE:"$myline done < datafile.txt 2.使用read命 ...

  3. shell脚本中每次读取文件的一行

    写法一: #!/bin/bash while read linedo      echo $line     #这里可根据实际用途变化 done < file          #需要读取的文件 ...

  4. python读取文件,python读取的1变成\ufeff1

    '\ufeff1' movies={} fm=open(self.path+'/movie.txt',encoding='utf-8') w2=open('./data/1.txt','a') for ...

  5. C++/Php/Python/Shell 程序按行读取文件或者控制台

    写程序经常需要用到从文件或者标准输入中按行读取信息,这里汇总一下.方便使用 1. C++ 读取文件 #include<stdio.h> #include<string.h> i ...

  6. PHP文件操作 之读取一个文件(以二进制只读的方式打开)

    最近应用了文件的读取,顺便复习一下! //读取一个文件 $f = fopen($filename,'rb'); $f: 表示返回的一个资源句柄 $filename:要打开的文件路径 rb:参数,表示只 ...

  7. 类似于c语言读取文件进行解析

    $log_file_name = 'D:/static/develop/kuai_zhi/acagrid.com/public/Logs/'.date('Ym').'/'.date('d').'_er ...

  8. C++/Php/Python/Shell 程序按行读取文件或者控制台方法总结。

    C++/Php/Python/Shell 程序按行读取文件或者控制台方法总结. 一.总结 C++/Php/Python/Shell 程序按行读取文件或者控制台(php读取标准输入:$fp = fope ...

  9. java中读取文件以及向文件中追加数据的总结

    package gys; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; imp ...

随机推荐

  1. leetcode 盛水最多的容器 解析

    采用双指针法: 主要思想:定义头尾两个指针,分别向中间遍历,当相遇时结束循环.存储每一次遍历容器盛水的最大容量,并不断更新. 盛水的最大容量为 左右指针高度的最小值 乘以 左右指针的距离即宽度. 则可 ...

  2. PHP中的PDO对象操作学习(一)初始化PDO及原始SQL语句操作

    PDO 已经是 PHP 中操作数据库事实上的标准.包括现在的框架和各种类库,都是以 PDO 作为数据库的连接方式.基本上只有我们自己在写简单的测试代码或者小的功能时会使用 mysqli 来操作数据库. ...

  3. Linux系列(9) - whoami和whatis

    whoami 作用:当前你登录的用户是谁 whatis [命令] 作用:查询[命令]是干嘛的 我们试一下对文件和目录whatis行不行,结果发现不行:但是有没有发现对命令whatis也不行,为什么呢: ...

  4. centos7.X 系统初始化>>优化

    1 修改网卡为eth0 cd /etc/sysconfig/network-scripts/ vim ifcfg-eno16777729TYPE=EthernetBOOTPROTO=staticIPA ...

  5. 小白自制Linux开发板 二. u-boot移植

    上一篇:小白自制Linux开发板 一. 瞎抄原理图与乱画PCB  中我们做了一个小型而没用的开发板,用的是Licheepi Nano的镜像,那从本篇开始我们开始自己构建它的灵魂吧. 我们都知道,PC在 ...

  6. Unity 刚体问题 解决相互作用力

    在进行开发过程中,当两个都具有碰撞体和刚体的 游戏物体进行接触之后,或多或少都会出现相互作用力,对于体验有一定的影响. 需要在FixedUpdate(间隔固定的时间调用,不受游戏帧率的影响)  当中  ...

  7. 演员 Or 开发者的自我修养

    演员 Or 开发者的自我修养 时至今日,我都还是很怀念小时候与一群玩伴编写剧本.拍摄,那时候的我还有一个远大的"白日梦"--成为一名导演.很可惜,终究是"白日梦" ...

  8. 题解 [AGC017C] Snuke and Spells

    题目传送门 Description 有 \(n\) 个球排在一起,每个球有颜色 \(a_i\),若当前有 \(k\) 个球,则会将所有 \(a_i=k\) 的球删掉.有 \(m\) 次查询,每次将 \ ...

  9. 【Azure 应用服务】App Service中运行Python 编写的 Jobs,怎么来安装Python包 (pymssql)呢?

    问题描述 在App Service中运行Python编写的定时任务,需要使用pymssql连接到数据库,但是发现使用 python.exe -m pip install --upgrade -r re ...

  10. Spring的JDK动态代理如何实现的(源码解析)

    前言 上一篇文章中提到了SpringAOP是如何决断使用哪种动态代理方式的,本文接上文讲解SpringAOP的JDK动态代理是如何实现的.SpringAOP的实现其实也是使用了Proxy和Invoca ...