You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

790 lines
30 KiB
C++

2 years ago
/*-----------------------------------------------------------------------------------
INI V1.65
2 years ago
2002.10.3
2 years ago
----------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------
[]:
2 years ago
(1) V1.0 2002.8.13 仿windowsAPI
2 years ago
(2) V1.1 2002.9.13 BUG
2 years ago
1.
2. ,
2 years ago
(3) V1.2 2002.9.18 QGetPrivateProfileInt()16
2 years ago
(4) V1.3 2002.9.19 BUG
2 years ago
1. StrTrimLeft, StrTrimRightTAB(ASC9),Ini
TAB
2. ";"StrTrimAll()
TAB
2 years ago
(5) V1.4a 2002.9.20
OpenPort()3016
2 years ago
(6) V1.41a 2002.9.23
,OpenPort()1614
,, ,沿-
2 years ago
(7) V1.5 2002.9.23
2 years ago
1. QGetPrivateProfileString(),
,,,INI
,
INI使
使
使OpenPort()3-4.
2 years ago
2. WritePrivateProfileString()10,
2 years ago
(8) V1.6 2002.9.27 ini
2 years ago
,(0x0A),fgets()
windowsini(0x0D),
0x0A,windows访unixini
2 years ago
(9) V1.65 2002.10.3 provdata.ini
1. "//"";"
2. '\'
2 years ago
:
1. ()
2. ,(';')('\')
2 years ago
-----------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------------
[使]:
2 years ago
(1) ,,unixOS_UNIX
(2) INI,:
'['']'INI"[ xxx ]"
"[xxx]"访
2 years ago
-------------------------------------------------------------------------------------*/
#include "string.h"
#include "stdio.h"
#include "common.h"
#include "inifile.h"
#include <stdlib.h>
2 years ago
//#include <qglobal.h>
/*-------------------------------------------------------------------------------------
INI(),API,const char*char*
DWORDint,(APIDWORD)
(int),使
2 years ago
-------------------------------------------------------------------------------------*/
int QGetPrivateProfileString(
const char* lpszSectionName, //段名
const char* lpszKeyName, //键名
const char* lpszDefault, //缺省字符串
char* lpszReturnedString, //结果字符串
u_32 nSize, //结果字符串长度
const char* lpszFileName, //ini文件名
const char* lpszRemarkInLineStr, //行内注释符
const char chContinueLineChar //续行符号
2 years ago
)
{
FILE* IniFile = NULL;
BOOL bSecFoundFlag = FALSE;
BOOL bKeyFoundFlag = FALSE;
BOOL bEOF = FALSE;
char szLineBuf[MAX_LINE_BUF_LENGTH]; //行缓冲区
char szKeyItemBuf[MAX_LINE_BUF_LENGTH*4]; //最终内容缓冲区(因键所在行可能因使用续行符而占据多行)
char *lpszFileText = NULL; //放置INI文件全部内容的字符串
char *lpszLineBegin = NULL; //一行开始指针
2 years ago
char *lpszTmp = NULL;
i_32 lFileSize = 0;
int iPos, iRetVal;
BOOL bLineContinue = FALSE; //2002.10.3 续行标志
2 years ago
/*---------------------------------------------------------------------------------
char szLineEndStr[3]; //行末尾换行符号
2 years ago
memset(szLineEndStr, 0, 3);
#ifdef OS_UNIX
strcpy(szLineEndStr, "\n"); //UNIX文本文件行末只有一个换行符'\n'
2 years ago
#else
strcpy(szLineEndStr, "\r\n"); //Windows文本文件行末有一个回车符'\r',一个换行符'\n'
2 years ago
#endif
----------------------------------------------------------------------------------*/
IniFile = fopen(lpszFileName, "rb"); //二进制可读方式打开(文件必须存在)
2 years ago
if(!IniFile)
{
//qDebug("fopen error, %s", lpszFileName);
return FILE_OPEN_ERROR;
}
fseek(IniFile, 0, SEEK_END); //定位到文件尾部
lFileSize = ftell(IniFile); //获取文件尾指针位置(该值=文件总长=文件指针位置最大值+1)
2 years ago
lpszFileText = new char[lFileSize+1];
memset(lpszFileText, 0, lFileSize+1);
fseek(IniFile, 0, SEEK_SET); //重新定位到开头
fread(lpszFileText, 1, lFileSize, IniFile); //将文件所有内容全部读入字符串
fclose(IniFile); //读入全部内容后立即关闭文件
2 years ago
lpszLineBegin = lpszFileText;
//段搜索
2 years ago
/*----------------------------------------------------------------------------
//while(!feof(IniFile))
while(!bEOF)
{
//ReadLineFromFile(IniFile, szLineBuf, MAX_LINE_BUF_LENGTH); //读取一行
2 years ago
memset(szLineBuf, 0, MAX_LINE_BUF_LENGTH);
lpszTmp = strstr(lpszLineBegin, szLineEndStr); //搜索换行符号来定位行末
2 years ago
if(lpszTmp != NULL)
{
strncpy(szLineBuf, lpszLineBegin, min(MAX_LINE_BUF_LENGTH-1, lpszTmp-lpszLineBegin));
lpszLineBegin = lpszTmp + strlen(szLineEndStr);
}
else //最后一行
2 years ago
{
strncpy(szLineBuf, lpszLineBegin, min(MAX_LINE_BUF_LENGTH-1, lpszFileText+lFileSize-lpszLineBegin));
bEOF = TRUE;
}
StrTrimAll(szLineBuf);
if( szLineBuf[0] == ';' || szLineBuf[0] == 0 ) continue; //注释行和空行不处理
2 years ago
//将一行尾部可能存在的";"注释部分剔除(这样key=value的value中不能含有;否则将被当成注释而删除
2 years ago
lpszTmp = strchr(szLineBuf, ';');
if(lpszTmp != NULL) *lpszTmp = 0;
StrTrimAll(szLineBuf); //zl 2002.9.19 ";"和有用内容间必有空格或TAB字符,必须删除这些分割字符
2 years ago
iPos = strlen(szLineBuf) - 1;
if(szLineBuf[0] == '[' && szLineBuf[iPos] == ']') //该行是一个段
2 years ago
{
szLineBuf[iPos] = 0; //去掉"["和"]",便于比较
2 years ago
lpszTmp = &szLineBuf[1];
if( strcmp(lpszTmp, lpszSectionName) == 0 ) //指定的段找到了
2 years ago
{
bSecFoundFlag = TRUE;
break;
}
}
}
----------------------------------------------------------------------------*/
//zl 2002.9.23 新的段搜索算法(直接在包含整个ini文件内容的字符串中定位段名)
2 years ago
char szFindStr[MAX_LINE_BUF_LENGTH]; //搜索字符串
2 years ago
sprintf(szFindStr, "[%s]", lpszSectionName);
while(!bEOF)
{
lpszTmp = strstr(lpszLineBegin, szFindStr);
if( lpszTmp != NULL ) //找到段名,继续验证其是否合法
2 years ago
{
lpszLineBegin = lpszTmp + strlen(szFindStr); //计算新的查找起始位置
2 years ago
if( lpszLineBegin > (lpszFileText + lFileSize -1) ) bEOF = TRUE;
if( lpszTmp == lpszFileText ) //"[xxx]"是文件的开头内容,为合法段名
2 years ago
{
bSecFoundFlag = TRUE;
break;
}
/*----------------------------------------------------------------------------
'[',0xA,,tab(ASC9)
,,, ']'
2 years ago
----------------------------------------------------------------------------*/
lpszTmp--;
while( lpszTmp >= lpszFileText )
{
if( *lpszTmp == 0xA )
{
bSecFoundFlag = TRUE;
break;
}
else if( *lpszTmp == ' ' || *lpszTmp == 9 )
lpszTmp--;
else
break;
}
if( bSecFoundFlag ) break; //退出外循环
2 years ago
}
else
break; //没找到段名,退出
2 years ago
}
if( !bSecFoundFlag )
{
iRetVal = SECTION_NOT_FOUND;
goto func_end;
}
//继续键搜索(定位段后,对于所属键的查找为逐行读取扫描方式,键可能占用多行)
2 years ago
while(!bEOF)
{
if( !bLineContinue )
memset(szKeyItemBuf, 0, sizeof(szKeyItemBuf)); //关键,控制多行连接
2 years ago
memset(szLineBuf, 0, MAX_LINE_BUF_LENGTH);
//zl 2002.9.27 为保证提取一行的操作与平台文件格式无关,只查找换行符(0x0A),这和fgets()类似
2 years ago
lpszTmp = strchr(lpszLineBegin, 0x0A);
if(lpszTmp != NULL)
{
strncpy(szLineBuf, lpszLineBegin, min(MAX_LINE_BUF_LENGTH-1, lpszTmp-lpszLineBegin)); //从字符串中提取一行
2 years ago
/* 读windows文本文件时,每行尾部多一个回车符(0x0D),必须去掉,否则后面连续出错 */
2 years ago
if( szLineBuf[strlen(szLineBuf)-1] == 0x0D )
szLineBuf[strlen(szLineBuf)-1] = 0;
lpszLineBegin = lpszTmp + 1; //1表示"0x0A"一个字符
2 years ago
}
else //最后一行
2 years ago
{
strncpy(szLineBuf, lpszLineBegin, min(MAX_LINE_BUF_LENGTH-1, lpszFileText+lFileSize-lpszLineBegin));
bEOF = TRUE;
}
StrTrimAll(szLineBuf);
//全注释行和空行不处理
2 years ago
if( szLineBuf[0] == ';' || szLineBuf[0] == 0 )
{
if( bLineContinue && strlen(szKeyItemBuf) > 0 ) //2002.10.7 如果前面是续行,则继续处理szKeyItemBuf已有内容而不是continue重新读入一行,否则当前行(空行或注释行)上面的一个续行的全部内容将丢失
2 years ago
bLineContinue = FALSE;
else
{
bLineContinue = FALSE;
continue;
}
}
else
{
//2002.10.3 判断续行,续行符为行末最后的一个非空格或TAB字符,缺省为'\'
2 years ago
if( szLineBuf[strlen(szLineBuf)-1] == chContinueLineChar )
{
bLineContinue = TRUE;
szLineBuf[strlen(szLineBuf)-1] = 0; //去掉续行符
2 years ago
StrTrimAll(szLineBuf);
strcat(szKeyItemBuf, szLineBuf);
continue;
}
else //无续行字符行
2 years ago
{
bLineContinue = FALSE;
strcat(szKeyItemBuf, szLineBuf);
}
}
//将一行尾部可能存在的行内注释部分(缺省行内注释符是";")剔除
2 years ago
//lpszTmp = strchr(szLineBuf, ';');
lpszTmp = strstr(szKeyItemBuf, lpszRemarkInLineStr); //2002.10.3 可以任意指定行内注释符
2 years ago
if(lpszTmp != NULL) *lpszTmp = 0;
StrTrimAll(szKeyItemBuf); //zl 2002.9.19 ";"和有用内容间必有空格或TAB字符,必须删除这些分割字符
2 years ago
iPos = strlen(szKeyItemBuf)-1;
if(szKeyItemBuf[0] == '[' && szKeyItemBuf[iPos] == ']') //又到了一个段说明指定段下的指定key没有找到
2 years ago
{
iRetVal = KEY_NOT_FOUND;
goto func_end;
}
lpszTmp = strchr(szKeyItemBuf, '='); //定位'='
if(lpszTmp == NULL) continue; //不含等号的非段行被视为无效行
2 years ago
*lpszTmp = 0; //为便于操作,在'='位置将szLineBuf从中间截断, 将szLineBuf分成key和value两个部分
StrTrimAll(szKeyItemBuf); //此时szLineBuf是key
2 years ago
if(strcmp(szKeyItemBuf, lpszKeyName) == 0) //找到了指定key
2 years ago
{
lpszTmp++;
StrTrimAll(lpszTmp); //lpszTmp++是key对应的value
2 years ago
if( strlen(lpszTmp) < nSize )
strcpy(lpszReturnedString, lpszTmp); //返回key对应的value
2 years ago
else
strncpy(lpszReturnedString, lpszTmp, strlen(lpszTmp));
iRetVal = 1; //1表示正确
2 years ago
bKeyFoundFlag = TRUE;
break;
}
}
if( !bKeyFoundFlag ) iRetVal = KEY_NOT_FOUND;
func_end:
delete [] lpszFileText;
//如果出错同时缺省参数不为NULL则返回缺省参数
2 years ago
if( iRetVal < 0 && lpszDefault != NULL )
{
if( strlen(lpszDefault) < nSize )
strcpy(lpszReturnedString, lpszDefault);
else
strncpy(lpszReturnedString, lpszDefault, strlen(lpszDefault));
}
return iRetVal;
}
/*-------------------------------------------------------------------------------------
INI(),API,const char*char*,
UINTint
2 years ago
-------------------------------------------------------------------------------------*/
int QGetPrivateProfileInt(
const char* lpszSectionName, //段名
const char* lpszKeyName, //键名
int nDefault, //缺省值
const char* lpszFileName, //ini文件名
const char* lpszRemarkInLineStr, //行内注释符
const char chContinueLineChar //续行符号
2 years ago
)
{
int iRet, iResult;
char szNumStr[256]; //数字字符串
2 years ago
iRet = QGetPrivateProfileString(
lpszSectionName, //段名
lpszKeyName, //键名
NULL, //缺省字符串
szNumStr, //结果字符串
256, //结果字符串长度
lpszFileName, //INI文件名
lpszRemarkInLineStr, //行内注释符
chContinueLineChar //续行符号
2 years ago
);
//qDebug(lpszFileName);
if(iRet < 0) return nDefault; //出错则返回缺省值
2 years ago
StrTrimAll(szNumStr);
/*--------------------------------------------------------------------------------
ini"0x1801"16,,atoi16
2002.9.18 16,"0x数字"
2 years ago
--------------------------------------------------------------------------------*/
BOOL bIsHexFlag = FALSE;
if( strlen(szNumStr) > 2 )
{
if( szNumStr[0] == '0' && szNumStr[1] == 'x' ) bIsHexFlag = TRUE;
}
if( bIsHexFlag )
iRet = sscanf(&szNumStr[2], "%x", &iResult); //16进制
2 years ago
else
iRet = sscanf(szNumStr, "%d", &iResult); //10进制
2 years ago
if( iRet != 1 ) //如数字字符串合法的话,应只转换一个field,故返回值不为1表示出错,此时返回缺省值
2 years ago
return nDefault;
else
return iResult; //正确返回
2 years ago
}
/*-------------------------------------------------------------------------------------
INI,API,const char*char*
2 years ago
-------------------------------------------------------------------------------------*/
BOOL QWritePrivateProfileString(
const char* lpszSectionName, //段名
const char* lpszKeyName, //键名
const char* lpszString, //要写入的字符串
const char* lpszFileName //INI文件名
2 years ago
)
{
FILE* IniFile;
char szLineBuf[MAX_LINE_BUF_LENGTH];
char *lpszFrontBlock = NULL, *lpszRearBlock = NULL; //装入前后两块文件各自所占的内存区指针
2 years ago
char *lpszTmp = NULL;
i_32 lPrePos = 0, lCurPos = 0; //前一次读取及本次读取的文件指针位置
2 years ago
bool bSecFoundFlag = FALSE;
bool bKeyFoundFlag = FALSE;
bool bMeetAnotherBlock = FALSE; //遇到另外一个段
2 years ago
i_32 lEndPos;
int iPos;
char szLineEndStr[3]; //行末尾换行符号
2 years ago
#ifdef OS_UNIX
strcpy(szLineEndStr, "\n"); //UNIX文本文件行末只有一个换行符'\n'
2 years ago
#else
strcpy(szLineEndStr, "\r\n"); //Windows文本文件行末有一个回车符'\r',一个换行符'\n'
2 years ago
#endif
IniFile = fopen(lpszFileName, "r+b"); //二进制方式打开,可读可写(但文件必须存在)
2 years ago
if(!IniFile) return false;
fseek(IniFile, 0, SEEK_END); //定位到文件尾部
lEndPos = ftell(IniFile); //计算文件尾部指针位置(该值=文件总长=文件指针位置最大值+1)
2 years ago
fseek(IniFile, 0, SEEK_SET); //重新定位到开头
2 years ago
//先找指定的section
2 years ago
while(!feof(IniFile))
{
lPrePos = lCurPos; //保留上次文件指针位置
2 years ago
ReadLineFromFile(IniFile, szLineBuf, MAX_LINE_BUF_LENGTH); //读取一行
2 years ago
lCurPos = ftell(IniFile); //当前文件指针位置
2 years ago
StrTrimAll(szLineBuf);
if( szLineBuf[0] == ';' || szLineBuf[0] == 0 ) continue; //注释行和空行不处理
2 years ago
//将一行尾部可能存在的";"注释部分剔除(这样key=value的value中不能含有;否则将被当成注释而删除
2 years ago
lpszTmp = strchr(szLineBuf, ';');
if(lpszTmp != NULL) *lpszTmp = 0;
StrTrimAll(szLineBuf); //zl 2002.9.19 ";"和有用内容间必有空格或TAB字符,必须删除这些分割字符
2 years ago
iPos = strlen(szLineBuf) - 1;
if(szLineBuf[0] == '[' && szLineBuf[iPos] == ']') //该行是一个段
2 years ago
{
szLineBuf[iPos] = 0; //去掉"["和"]",便于比较
2 years ago
lpszTmp = &szLineBuf[1];
if( strcmp(lpszTmp, lpszSectionName) == 0 ) //指定的段找到了
2 years ago
{
bSecFoundFlag = TRUE;
break;
}
}
}
//[情况一]:如果未找到指定段,则指定key肯定也不存在,因此即要新建section也要新建key,
// 这些内容就直接追加到文件尾部,同时约定在文件尾部新建一个段时,默认在前面
// 追加换行符号以确保和前面的其它内容不在一行
2 years ago
if( !bSecFoundFlag )
{
char szNewSection[2048];
memset(szNewSection, 0, 2048);
//生成新的段字符串
2 years ago
sprintf(szNewSection, "%s[%s]%s%s = %s%s", szLineEndStr, lpszSectionName, szLineEndStr, lpszKeyName, lpszString, szLineEndStr);
fseek(IniFile, 0, SEEK_END);
fwrite(szNewSection, sizeof(char), strlen(szNewSection), IniFile);
goto func_end;
}
//找到指定段后再继续找指定key
2 years ago
while(!feof(IniFile))
{
lPrePos = lCurPos; //保留上次文件指针位置
2 years ago
ReadLineFromFile(IniFile, szLineBuf, MAX_LINE_BUF_LENGTH); //读取一行
2 years ago
lCurPos = ftell(IniFile); //保留当前文件指针位置
2 years ago
StrTrimAll(szLineBuf);
if( szLineBuf[0] == ';' || szLineBuf[0] == 0 ) continue; //注释行和空行不处理
2 years ago
//将一行尾部可能存在的";"注释部分剔除(这样key=value的value中不能含有;否则将被当成注释而删除
2 years ago
lpszTmp = strchr(szLineBuf, ';');
if(lpszTmp != NULL) *lpszTmp = 0;
StrTrimAll(szLineBuf); //zl 2002.9.19 ";"和有用内容间必有空格或TAB字符,必须删除这些分割字符
2 years ago
iPos = strlen(szLineBuf)-1;
if(szLineBuf[0] == '[' && szLineBuf[iPos] == ']')
{
bMeetAnotherBlock = TRUE; //又到了一个段说明指定段下的指定key没有找到
2 years ago
break;
}
lpszTmp = strchr(szLineBuf, '='); //定位'='
if(lpszTmp == NULL) continue; //不含等号的非段行被视为无效行
2 years ago
*lpszTmp = 0; //为便于操作,在'='位置将szLineBuf从中间截断, 将szLineBuf分成key和value两个部分
StrTrimAll(szLineBuf); //此时szLineBuf是key
2 years ago
/* 找到了指定key */
2 years ago
if(strcmp(szLineBuf, lpszKeyName) == 0) //该比较大小写敏感
2 years ago
{
char szKeyValBlock[2048];
memset(szKeyValBlock, 0, 2048);
//重新组织key = value对实现修改目的
2 years ago
sprintf(szKeyValBlock, "%s = %s%s", szLineBuf, lpszString, szLineEndStr);
//注意这里和下面的段前插入内容不同这里是要将原有的key=value对去掉
//代之以新对,因此lPrePos和lCurPos之间的文件内容(即原有key=value对)不要,
//该操作是替换而不是插入
2 years ago
lpszRearBlock = new char[lEndPos-lCurPos+1];
memset(lpszRearBlock, 0, lEndPos-lCurPos+1);
fread(lpszRearBlock, sizeof(char), lEndPos-lCurPos, IniFile); //从当前位置开始读其后面的文件内容(长度为lEndPos-lCurPos, 注意lEndPos是end结尾符号的位置,等于文件长度,比最大有效文件指针位置大1)
2 years ago
lpszFrontBlock = new char[lPrePos+1];
memset(lpszFrontBlock, 0, lPrePos+1);
fseek(IniFile, 0, SEEK_SET);
fread(lpszFrontBlock, sizeof(char), lPrePos, IniFile); //从头部开始读其后面的文件内容(长度为lPrePos,因为文件指针从0开始,lPrePos位置前的文件长度就是lPrePos)
2 years ago
//先关闭文件再用可写方式打开以清空原有内容,最后依次写文件的各个部分,如要不关闭
//打开文件而是直接清空文件内容,因unix和windows中设置文件长度的调用不同,比较麻烦
2 years ago
fclose(IniFile);
IniFile = fopen(lpszFileName, "wb"); //可写方式打开(如文件已存在,其所有内容被清空)
2 years ago
if(!IniFile) return FALSE;
fwrite(lpszFrontBlock, sizeof(char), lPrePos, IniFile);
fwrite(szKeyValBlock, sizeof(char), strlen(szKeyValBlock), IniFile);
fwrite(lpszRearBlock, sizeof(char), lEndPos-lCurPos, IniFile);
delete [] lpszFrontBlock;
delete [] lpszRearBlock;
bKeyFoundFlag = TRUE;
break;
}
}
//如果在指定段下未找到指定key,则要新建key=value对
2 years ago
if( !bKeyFoundFlag )
{
char szKeyBlock[2048];
memset(szKeyBlock, 0, 2048);
if(bMeetAnotherBlock) //遇到了另外一个段,此时要在该段前面插入新建的key=value对
2 years ago
{
sprintf(szKeyBlock, "%s = %s%s", lpszKeyName, lpszString, szLineEndStr);
//以下以lPrePos为界线将文件拆成两部分,和上面替换操作中lPrePos和lCurPos间内容
//不要不同,这里是插入而不是替换, 因此直接以lPrePos为界将文件分开,进行插入操作
2 years ago
fseek(IniFile, lPrePos, SEEK_SET); //定位到lPrePos(这里lPrePos是另一个段的开始字符,如"[")
2 years ago
lpszRearBlock = new char[lEndPos-lPrePos+1];
memset(lpszRearBlock, 0, lEndPos-lPrePos+1);
fread(lpszRearBlock, sizeof(char), lEndPos-lPrePos, IniFile); //从当前位置开始读其后面的文件内容(长度为lEndPos-lPrePos)
2 years ago
lpszFrontBlock = new char[lPrePos+1];
memset(lpszFrontBlock, 0, lPrePos+1);
fseek(IniFile, 0, SEEK_SET);
fread(lpszFrontBlock, sizeof(char), lPrePos, IniFile); //从头部开始读其后面的文件内容(长度为lPrePos)
2 years ago
//先关闭文件再用可写方式打开以清空原有内容,最后依次写文件的各个部分,如要不关闭
//打开文件而是直接清空文件内容,因unix和windows中设置文件长度的调用不同,比较麻烦
2 years ago
fclose(IniFile);
IniFile = fopen(lpszFileName, "wb"); //可写方式打开(如文件已存在,其所有内容被清空)
2 years ago
if(!IniFile) return FALSE;
fwrite(lpszFrontBlock, sizeof(char), lPrePos, IniFile);
fwrite(szKeyBlock, sizeof(char), strlen(szKeyBlock), IniFile);
fwrite(lpszRearBlock, sizeof(char), lEndPos-lPrePos, IniFile);
delete [] lpszFrontBlock;
delete [] lpszRearBlock;
}
else //如果连一个段都没有碰到,则肯定已到了文件尾部, 追加key=value块到尾部即可
2 years ago
{
fseek(IniFile, 0, SEEK_END);
/* 如当前位置前已有换行符号则无需另行增加,此举可防止新增部分和上面一行连在一起 */
2 years ago
if( IfBeforeHasRet(IniFile) )
sprintf(szKeyBlock, "%s = %s%s", lpszKeyName, lpszString, szLineEndStr);
else
sprintf(szKeyBlock, "%s%s = %s%s", szLineEndStr, lpszKeyName, lpszString, szLineEndStr);
fwrite(szKeyBlock, sizeof(char), strlen(szKeyBlock), IniFile);
}
}
func_end:
fclose(IniFile);
return true;
}
//辅助函数,判断文件中当前指针位置前面是否有换行符号,使用该函数前必须确保文件已经打开并将文件指针定位到应有的位置
2 years ago
bool IfBeforeHasRet(FILE* pFile)
{
char szTmp[3];
bool bBeforeHasRet = FALSE;
i_32 lOldPos;
memset(szTmp, 0, 3);
lOldPos = ftell(pFile); //保存文件当前指针位置
2 years ago
/* 读当前位置前面的两个字节, 因为windows下是回车换行两个字节 */
2 years ago
fseek(pFile, -2, SEEK_CUR);
fread(szTmp, sizeof(char), 2, pFile);
#ifdef OS_UNIX
if( szTmp[1] == 0x0a ) bBeforeHasRet = TRUE;
#else
if( szTmp[0] == 0x0d && szTmp[1] == 0x0a ) bBeforeHasRet = TRUE;
#endif
fseek(pFile, lOldPos, SEEK_SET); //恢复原先的文件指针位置
2 years ago
return bBeforeHasRet;
}
/*-----------------------------------工具函数----------------------------------*/
2 years ago
//从指定文件中读取一行
2 years ago
int ReadLineFromFile(FILE* IniFile, char* lpszLineBuf, int iLen)
{
int iPos;
/*-----------------------------------------------------------------------------
ttextinput
fgets()binary
fgets
text
binary
textbinary,WindowsUnix
(unix0A,)
2 years ago
: fopen()"t"Ansi C "b"
2 years ago
----------------------------------------------------------------------------*/
if(fgets(lpszLineBuf, iLen, IniFile) != NULL) //fgets()函数遇到第一个换行符(0x0A)后结束(包括换行符),然后在尾部追加一个NULL后返回,因此换行符总是倒数第二个字符
2 years ago
{
iPos = strlen(lpszLineBuf) - 1;
if( lpszLineBuf[iPos-1] == 0x0D ) lpszLineBuf[iPos-1] = 0; //删除尾部可能存在的回车符(0x0D)
if( lpszLineBuf[iPos] == 0x0A ) lpszLineBuf[iPos] = 0; //删除尾部可能存在的换行符(0x0A)
2 years ago
}
else
return -1;
return 0; //0表示正确
2 years ago
}
/*----------------------------------------------------------------------------
//从指定字符串中读取一行
2 years ago
int ReadLineFromString(char* lpszText, char* lpszLineBuf, int iLen)
{
int iPos;
if(fgets(lpszLineBuf, iLen, IniFile) != NULL) //fgets()函数遇到第一个换行符(0x0A)后结束(包括换行符),然后在尾部追加一个NULL后返回,因此换行符总是倒数第二个字符
2 years ago
{
iPos = strlen(lpszLineBuf) - 1;
if( lpszLineBuf[iPos-1] == 0x0D ) lpszLineBuf[iPos-1] = 0; //删除尾部可能存在的回车符(0x0D)
if( lpszLineBuf[iPos] == 0x0A ) lpszLineBuf[iPos] = 0; //删除尾部可能存在的换行符(0x0A)
2 years ago
}
else
return -1;
return 0; //0表示正确
2 years ago
}
---------------------------------------------------------------------------*/
//删除字符串的左侧空格, 2002.9.19增加删除TAB字符(ASC码为9)功能
2 years ago
void StrTrimLeft(char* szBuf)
{
char *szBak = NULL;
char *p = szBuf;
if(!szBuf) return;
while(*p == ' ' || *p == 9) { p++; }
//qDebug("StrtrimLeft:p=%s",p);
if(p != szBuf) //头部有空格或TAB字符
2 years ago
{
szBak = _strdup(p); //strcpy()中如source和dest重合(overlap)则copy结果不可预料故另设一个缓冲区临时存放这个头部没有空格的字符串
strcpy(szBuf, szBak); //strcpy()肯定不会溢出因p是szBuf的一个子集同时strcpy会拷贝结尾的null因此无须人工截断szBuf
2 years ago
free(szBak);
}
}
//删除字符串的右侧空格, 2002.9.19增加删除TAB字符(ASC码为9)功能
2 years ago
void StrTrimRight(char* szBuf)
{
char *szBak = NULL;
int iPos = strlen(szBuf)-1; //最后一个非NULL字符的下标
2 years ago
if(!szBuf) return;
char *p = &szBuf[iPos];
while(*p == ' ' || *p == 9) { p--; }
if(p != &szBuf[iPos]) //尾部有空格
2 years ago
{
p++;
*p = 0; //直接尾部截断,比删除头部空格还简单
2 years ago
}
}
//删除左右两边所有空格
2 years ago
void StrTrimAll(char* szBuf)
{
StrTrimRight(szBuf);
StrTrimLeft(szBuf);
}
//获取指定文件的长度
2 years ago
i_32 GetFileSize(char* lpszFileName)
{
FILE* pFile;
pFile = fopen(lpszFileName, "rb"); //二进制方式
2 years ago
if(pFile == NULL) return -1;
fseek(pFile, 0, SEEK_END); //定位到文件尾部
i_32 lFileSize = ftell(pFile); //获取文件指针当前位置(此时文件指针指向EOF结束标志)[文件指针是从0开始计数的]
2 years ago
fclose(pFile);
return lFileSize;
}