fscanf读取INI文件时键名部分重合问题

公司以前的项目中有的是用fscanf来读取INI文件,这会产生不少问题,键名部分重合便是一个不常出现,但可能出现的问题。

这里指的键名部分重合是指在同一节(Section)中,键名间出现类似如下情况:

NameAltitude=100
Sort=10
NameOffsetY=20

以上3个字段均是可选项,其中NameAltitude和NameOffsetY的第一个单词出现了重合。NameOffsetY是后来功能需要再添加上去。使用fscanf读取INI文件数据相关代码如下:

bool bSucRead = true;

// ...
// ...
// ...

// 读取必选键值-Begin
bSucRead &= fscanf(fp, "Name=%s\n", pInfo->szName);
bSucRead &= fscanf(fp, "SizeAdd=%d\n", &pInfo->nSizeAdd);
// ...
// ...
// ...
// 读取必选键值-End

// 读取可选键值-Begin
// ...
// ...
// ...
if (!fscanf(fp, "NameAltitude=%d\n", &pInfo->nNameAltitude))
{
    pInfo->nNameAltitude = 0;
}

if (!fscanf(fp, "Sort=%d\n", &pInfo->nSort))
{
    pInfo->nSort = 0;
}

if (!fscanf(fp, "NameOffsetY=%d\n", &pInfo->nNameOffsetY))
{
    pInfo->nNameOffsetY = 0;
}
// ...
// ...
// ...
// 读取可选键值-End

当有NameOffsetY前面至少有NameAltitude存在时,如下:

[003]
Name=monster
SizeAdd=23
...
...
...
NameAltitude=123
Sort=14
NameOffsetY=20

或者

[022]
Name=monster
SizeAdd=23
...
...
...
NameAltitude=123
NameOffsetY=20

此时数据读取正常。

而当从NameAltitude到NameOffsetY之前的字段都不存在时,如下:

[041]
Name=monster
SizeAdd=23
...
...
...
NameOffsetY=25

NameOffsetY读取失败,pInfo->nNameOffsetY被赋予默认值0,而不是25。

当文件指针走到"NameOffsetY"前时,fscanf却在准备读取"NameAltitude",结果前面的"Name"被读取了,然而到后面才发现读取错误,但文件指针已经走到"Altitude"前了。fscanf继续往后判断,读取"NameOffsetY"必然是失败的,因此pInfo->nNameOffsetY被赋予默认值0。

解决方案一:使用GetPrivateProfileInt、GetPrivateProfileInt等WIN32 API函数来读取INI文件。

解决方案二:使用现有框架下的CMyIni读取INI文件。

解决方案三:在发现读取错误后,让文件指针退会正确位置,可使用ftell和fseek来实现:

// 调整文件指针位置
inline bool AdjustFilePtrPos(FILE* fp, long lPosBeforeOffset)
{
    if (NULL != fp)
    {
        long lOffset = ftell(fp) - lPosBeforeOffset;
        if (0 < lOffset)
        {
            fseek(fp, -lOffset, SEEK_CUR);
            return true;
        }
    }
    return false;
}

//....
//....
//....
long lPosBeforeOffset = ftell(fp); // 记录文件指针出错前位置
if (!fscanf(fp, "NameAltitude=%d\n", &pInfo->nNameAltitude))
{
    pInfo->nNameAltitude = 0;
    AdjustFilePtrPos(fp, lPosBeforeOffset); // 调整文件指针位置
}
//....
//....
//....

原文地址:https://www.cnblogs.com/wxxweb/p/2246508.html