• 用C读取INI配置文件


    http://blog.csdn.net/chexlong/article/details/6818017

    #define CONF_FILE_PATH "Config.ini"

    #include <string.h>

    #ifdef WIN32
    #include <Windows.h>
    #include <stdio.h>
    #else

    #define MAX_PATH 260

    #include <unistd.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdarg.h>
    #endif

    char g_szConfigPath[MAX_PATH];

    //获取当前程序目录
    int GetCurrentPath(char buf[],char *pFileName)
    {
    #ifdef WIN32
    GetModuleFileName(NULL,buf,MAX_PATH);
    #else
    char pidfile[64];
    int bytes;
    int fd;

    sprintf(pidfile, "/proc/%d/cmdline", getpid());

    fd = open(pidfile, O_RDONLY, 0);
    bytes = read(fd, buf, 256);
    close(fd);
    buf[MAX_PATH] = '';

    #endif
    char * p = &buf[strlen(buf)];
    do
    {
    *p = '';
    p--;
    #ifdef WIN32
    } while( '\' != *p );
    #else
    } while( '/' != *p );
    #endif

    p++;

    //配置文件目录
    memcpy(p,pFileName,strlen(pFileName));
    return 0;
    }

    //从INI文件读取字符串类型数据
    char *GetIniKeyString(char *title,char *key,char *filename)
    {
    FILE *fp;
    char szLine[1024];
    static char tmpstr[1024];
    int rtnval;
    int i = 0;
    int flag = 0;
    char *tmp;

    if((fp = fopen(filename, "r")) == NULL)
    {
    printf("have no such file ");
    return "";
    }
    while(!feof(fp))
    {
    rtnval = fgetc(fp);
    if(rtnval == EOF)
    {
    break;
    }
    else
    {
    szLine[i++] = rtnval;
    }
    if(rtnval == ' ')
    {
    #ifndef WIN32
    i--;
    #endif
    szLine[--i] = '';
    i = 0;
    tmp = strchr(szLine, '=');

    if(( tmp != NULL )&&(flag == 1))
    {
    if(strstr(szLine,key)!=NULL)
    {
    //注释行
    if ('#' == szLine[0])
    {
    }
    else if ( '/' == szLine[0] && '/' == szLine[1] )
    {

    }
    else
    {
    //找打key对应变量
    strcpy(tmpstr,tmp+1);
    fclose(fp);
    return tmpstr;
    }
    }
    }
    else
    {
    strcpy(tmpstr,"[");
    strcat(tmpstr,title);
    strcat(tmpstr,"]");
    if( strncmp(tmpstr,szLine,strlen(tmpstr)) == 0 )
    {
    //找到title
    flag = 1;
    }
    }
    }
    }
    fclose(fp);
    return "";
    }

    //从INI文件读取整类型数据
    int GetIniKeyInt(char *title,char *key,char *filename)
    {
    return atoi(GetIniKeyString(title,key,filename));
    }

    int main(int argc, char* argv[])
    {
    char buf[MAX_PATH];
    memset(buf,0,sizeof(buf));
    GetCurrentPath(buf,CONF_FILE_PATH);
    strcpy(g_szConfigPath,buf);

    int iCatAge;
    char szCatName[32];

    iCatAge = GetIniKeyInt("CAT","age",g_szConfigPath);
    strcpy(szCatName,GetIniKeyString("CAT","name",g_szConfigPath));

    return 0;
    }

    感觉作者的程序还有几处bug
    第86行
    #ifndef WIN32 
    i--; 
    #endif 
    这个地方如果是吧linux下的配置文件拿到windows上用呢,又假如我用editplus或者ultraedit等工具修改了文件换行方式呢?
    应改为
    if(szLine[i-1] == ' ') {
    i--;
    }
    第95行,
    if(strstr(szLine,key)!=NULL) 
    判断szLine中不含有key字符串后,应该将szLine清零,以备下次循环的时候使用,所以这个地方应该加一个else语句
    else
    {
    memset(szLine,0,1024);
    }
    第76行,
    if(rtnval == EOF) 
    这个地方如果判断文件结尾了就退出,但是如果配置文件的最后一行的末尾是EOF的话,这个地方就出错了
    即最后一行是这种情况
    xxxxxxEOF
    如果最后一行是如下情况的话,是能通过的,作者肯定是只考虑了这种情况
    xxxxxx
    EOF
    所以这个地方应该改为
    if(rtnval == EOF && sizeof(szLine) != 0)

    还有就是顺便提一下作者的main函数中第148行,
    strcpy(szCatName,GetIniKeyString("CAT","name",g_szConfigPath));
    我也不是很推荐这么写,你程序内部的是按照每行1024个处理的,所以这个地方还是写成strncpy比较好。

  • 相关阅读:
    黑名单项目
    MVC
    《Spring敲门砖之基础教程第一季》 第一章 概要介绍
    【推荐】Java工程师如何从普通成为大神值得一读
    Spring框架知识总结-注入Bean的各类异常
    循序渐进Socket网络编程(多客户端、信息共享、文件传输)
    Struts2:ValueStack
    Struts2 的国际化实现
    一位10年程序员生涯的骨灰给小弟弟小妹妹们的一些总结性忠告
    集合类接口和类层次关系图
  • 原文地址:https://www.cnblogs.com/whwywzhj/p/8603552.html
Copyright © 2020-2023  润新知