有关fgetc配合feof逐行读取文件最后OA现金盘平台出租一行读取两遍的错觉

有关fgetc配合feof逐行读取文件最后OA现金盘平台出租QQ2952777280【话仙源码论坛】hxforum.com【木瓜源码论坛】papayabbs.com一行读取两遍的错觉?
最近在做一个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,清空缓存。

猜你喜欢

转载自blog.51cto.com/13881059/2148088