C语言读写ini文件 windows DOS(\r\n 0x0D 0X0A)或Linux (\n 0x0A) 两种格式都可以

 直接删所有\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;  
}

不存在就加入 待完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小黄人软件

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值