直接删所有\r 即0x0A就一样了。
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#define CONF_FILE_PATH "config.ini"
#define NOEXIST "No exist"
#define LINE_MAX_LENGTH 1024
//功能:从字符串中str删除所有某字符target
void delete_char(char str[],char target)
{
int i,j;
for(i=j=0;str[i]!='\0';i++)
{
if(str[i]!=target)
{
str[j++]=str[i];
}
}
str[j]='\0';
}
/*
* 函数名: GetIniKeyString
* 入口参数: title
* 配置文件中一组数据的标识
* key
* 这组数据中要读出的值的标识
* filename
* 要读取的文件路径
* 返回值: 找到需要查的值则返回正确结果
* 否则返回NULL
*/
char *GetIniKeyString(char *title,char *key,char *filename)
{
FILE *fp;
int flag = 0;
char sTitle[strlen(title)+5], *wTmp;
char sLine[LINE_MAX_LENGTH] ;
sprintf(sTitle, "[%s]", title);
if(NULL == (fp = fopen(filename, "r"))) {
perror("fopen");
return NULL;
}
printf("%s %s %s=",filename,sTitle,key);
while (NULL != fgets(sLine, sizeof(sLine), fp)) { //从指定的流 stream 读取一行,并把它存储在 str 所指向的字符串内。当读取 (n-1) 个字符时,或者读取到换行符时,或者到达文件末尾时,它会停止
//printf("Line:%s\n",sLine);
delete_char(sLine,'\r'); //兼容windows DOS
if (0 == strncmp("//", sLine, 2)) continue; //把 str1 和 str2 进行比较,最多比较前 n 个字节。 // 这是注释行
if ('#' == sLine[0]) continue;
wTmp = strchr(sLine, '='); //可以查找字符串s中首次出现字符=的位置。
if ((NULL != wTmp) && (1 == flag)) {
if (0 == strncmp(key, sLine, wTmp-sLine)) { // 长度依文件读取的为准
sLine[strlen(sLine) -1] = '\0'; //行尾截断
fclose(fp);
printf("%s\n",wTmp + 1); //=号后的字符串
return wTmp + 1;
}
} else {
if (strlen(sLine)>1 && 0 == strncmp(sTitle, sLine, strlen(sTitle))) { // 长度依文件读取的为准 \r\n去掉
// printf("\nsTitle:%sH sLine:%sH,sLineLen:%ld\n",sTitle,sLine,strlen(sLine) - 1);
flag = 1; // 找到标题位置
}
}
}
fclose(fp);
printf(NOEXIST"\n");
return NOEXIST;
}
/*
* 函数名: GetIniKeyInt
* 入口参数: title
* 配置文件中一组数据的标识
* key
* 这组数据中要读出的值的标识
* filename
* 要读取的文件路径
* 返回值: 找到需要查的值则返回正确结果
* 否则返回NULL
*/
int GetIniKeyInt(char *title,char *key,char *filename)
{
return atoi(GetIniKeyString(title, key, filename));
}
/**
* 更改配置 ,存在就改,不存在就失败
* @filename 文件名
* @title 段
* @key
* @val
* @return 成功1 失败0
*/
int SetIniKeyString(char *filename,char *title,char *key,char *val)
{
FILE *fpr, *fpw;
int flag = 0;
char sLine[LINE_MAX_LENGTH], sTitle[strlen(title)+5], *wTmp;
sprintf(sTitle, "[%s]", title);
printf("%s %s %s=%s\n",filename,sTitle,key,val);
if (NULL == (fpr = fopen(filename, "r"))) // 读取原文件
{
perror("fopen r");
return 0;
}
sprintf(sLine, "%s.tmp", filename);
if (NULL == (fpw = fopen(sLine, "w"))) // 写入临时文件
{
perror("fopen w");
return 0;
}
while (NULL != fgets(sLine, sizeof(sLine), fpr)) {//1 title和key都存在,更改值,2 title存在 ,key不存在,3title key都不存在
if (2 != flag) { // 如果找到要修改的那一行,则不会执行内部的操作
//delete_char(sLine,'\r'); //兼容windows DOS
if (0 == strncmp("//", sLine, 2)) continue; //把 str1 和 str2 进行比较,最多比较前 n 个字节。 // 这是注释行
if ('#' == sLine[0]) continue;
wTmp = strchr(sLine, '=');
if ((NULL != wTmp) && (1 == flag)) {
if (0 == strncmp(key, sLine, wTmp-sLine)) { // 长度依文件读取的为准
flag = 2;// 更改值,方便写入文件
sprintf(wTmp + 1, "%s\r\n", val); //windows
printf("更改值 %s:%d\n", __FILE__, __LINE__);
}
} else {
if ( 0 == strncmp(sTitle, sLine, strlen(sTitle))) { // 长度依文件读取的为准 \r\n 去掉\r长度 兼容windows DOS Linux
flag = 1; // 找到标题位置
}
}
}
fputs(sLine, fpw); // 写入临时文件
}
fclose(fpr);
fclose(fpw);
sprintf(sLine, "%s.tmp", filename);
if(2==flag)//替换了
{
int ret=rename(sLine, filename); // 将临时文件更新到原文件
if(ret == 0)
{
//printf("文件重命名成功");
remove(sLine);//删除临时文件
return 1;
}
else
{
printf("error,重名名文件失败。%s:%d\n", __FILE__, __LINE__);
}
}
printf("error,操作失败。flag=%d %s:%d\n",flag, __FILE__, __LINE__);
remove(sLine);//删除临时文件
return 0;
}
int main(int argc,char *argv[])
{
GetIniKeyString("info", "sn", "uart.ini");
GetIniKeyInt("ac380", "address", "uart.ini");
return 0;
}
不存在就加入 待完成。