C语言实现的配置文件读取功能,喜欢的拿去用.

1. 首先声明, 代码主要是从Linux udev程序中提取出来的. 

2.  支持的配置文件格式如下:

 

#comment

var_name1 = "XXX"                  #comment

var_name2 = "QQQ"                #comment

 

3. config_file.h

 

#include <stdint.h>
#include <stdio.h>
#include <syslog.h>

#define    MAX_PATH_LEN         (512)
#define    MAX_FILE_NAME_LEN    (128)

 

/* 将配置文件中的配置项解析后存放到全局数组中 */

int parse_config_file(char *path_to_config_file);  

 

/* 从全局数组中读取一个个配置项。例如  get_config_var("var_name1");  */
char * get_config_var(char *var_name);  

4.  config_file.c

 

#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <ctype.h>

#include <syslog.h>
#include <fcntl.h>
#include <sys/resource.h>
#include <signal.h>

#include "config_file.h"

#define    MAX_VAR_NUM          (16)
#define    MAX_VAR_NAME_LEN     (128)
#define    MAX_VAR_VALUE_LEN    (MAX_PATH_LEN)


#define COMMENT_CHARACTER   '#'
#define LINE_SIZE    (768)

 

char ga_variables[MAX_VAR_NUM][MAX_VAR_NAME_LEN + 1];
char ga_values[MAX_VAR_NUM][MAX_VAR_VALUE_LEN + 1];
int  g_var_num = 0;

void get_dir_path_of_file(char *file, char *dir_path)
{
 char *temp;
    strncpy(dir_path, file, MAX_PATH_LEN);
    temp = strrchr(dir_path, '/');
    temp[0] = '\0';

}

void remove_trailing_chars(char *path, char c)
{
 size_t len;

 len = strlen(path);
 while (len > 0 && path[len-1] == c)
  path[--len] = '\0';
}

int get_key(char **line, char **key, char **value)
{
 char *linepos;
 char *temp;

 linepos = *line;
 if (!linepos)
    {  
  return -1;
    }

 /* skip whitespace */
 while (isspace(linepos[0]))
  linepos++;

 if (linepos[0] == '\0')
    {  
  return -1;
    }

 /* get the key */
 *key = linepos;
 while (1) {
  linepos++;
  if (linepos[0] == '\0')
        {
   return -1;
        }
  if (isspace(linepos[0]))
   break;
  if (linepos[0] == '=')
   break;
 }

 /* terminate key */
 linepos[0] = '\0';

 while (1) {
  linepos++;
  if (linepos[0] == '\0')
        {
   return -1;
        }
  if (isspace(linepos[0]))
   continue;
  if (linepos[0] == '=')
   continue;
        break;
 }


 /* get the value*/
 if (linepos[0] == '"')
    {  
  linepos++;
    }
 else
    {
  return -1;
    }
 *value = linepos;

 temp = strchr(linepos, '"');
 if (!temp)
    {
  return -1;
    }
   
 temp[0] = '\0';
 return 0;
}


int parse_config_file(char *path_to_config_file)
{
 char line[LINE_SIZE + 2];
 char *bufline;
 char *linepos;
 char *variable;
 char *value;
 char *buf;
 size_t bufsize;
 size_t cur;
 size_t count;
 int lineno;
 int retval = 0;

    FILE *cfg_file = fopen(path_to_config_file, "r");
 if (NULL == cfg_file)
    {
  ErrSysLog("can't open '%s' as config file: %s", path_to_config_file, strerror(errno));
  goto EXIT;
 }

 /* loop through the whole file */
 lineno = 0;
 cur = 0;
 while (NULL != fgets(line, sizeof(line), cfg_file))
    {
  lineno++;
  bufline = line;
  count = strlen(line);

  if (count > LINE_SIZE)
        {
   ErrSysLog("line too long, conf line skipped %s, line %d", path_to_config_file, lineno);
   continue;
  }

  /* eat the whitespace */
  while ((count > 0) && isspace(bufline[0]))
        {
   bufline++;
   count--;
  }
  if (count == 0)
   continue;

  /* see if this is a comment */
  if (bufline[0] == COMMENT_CHARACTER)
   continue;

  memcpy(line, bufline, count);
  line[count] = '\0';

  linepos = line;
  retval = get_key(&linepos, &variable, &value);
  if (retval != 0)
        {
   ErrSysLog("error parsing %s, line %d:%d", path_to_config_file, lineno, (int)(linepos-line));
   continue;
  }

        if (g_var_num >= MAX_VAR_NUM)
        {
   ErrSysLog("too many vars in  %s, line %d:%d", path_to_config_file, lineno, (int)(linepos-line));
   continue;
  }

        if (strlen(variable) > MAX_VAR_NAME_LEN)
        {
   ErrSysLog("var name to long %s, line %d:%d", path_to_config_file, lineno, (int)(linepos-line));
   continue;
  }

        if (strlen(value) > MAX_VAR_VALUE_LEN)
        {
   ErrSysLog("value to long %s, line %d:%d", path_to_config_file, lineno, (int)(linepos-line));
   continue;
  }

  strncpy(ga_variables[g_var_num], variable, sizeof(ga_variables[g_var_num]));
        remove_trailing_chars(value, '/');
  strncpy(ga_values[g_var_num], value, sizeof(ga_values[g_var_num]));
        g_var_num++;
        continue;

 }
EXIT:
 fclose(cfg_file);
 return g_var_num;
}

char * get_config_var(char *var_name)
{
    int i;
 for(i = 0; i < g_var_num; i++)
    {
  if (strcasecmp(ga_variables[i], var_name) == 0)
        {
   return ga_values[i];
  }

    }
    ErrSysLog("get %s failed", var_name);
 return NULL;
   
}

void print_all_vars()
{
    int i;
    ErrPrintf("g_var_num == %d", g_var_num);
 for(i = 0; i < g_var_num; i++)
    {
        printf("%s = %s\n", ga_variables[i], ga_values[i]);

    }
   
   
}

 

 

 

你可能感兴趣的:(c,File,语言,Path,variables,whitespace)