运维开发网

用C实现添加和读取配置文件函数

运维开发网 https://www.qedev.com 2020-02-13 11:43 出处:网络 作者: 网络整理
本篇文章是对用C语言实现添加和读取配置文件函数的方法进行了详细的分析介绍,需要的朋友参考下
发现读取配置文件, 还是用得比较多的. 网上搜了下, 有不少的代码范例了.

不过一般实现的函数需要传递的参数都有配置文件的路径.

个人认为在某些情况下参数传入 流 重用性更大一点.

本想基于流的参数将 读取, 添加, 删除, 修改 配置文件的函数全部实现. 但发现

删除 , 修改 需要重新打开流, 单纯传入一个流参数不能方便实现.

以下是读取, 添加 配置的函数实现.

"oper_config.h"

复制代码 代码如下:

#ifndef OPER_CONFIG_H_

#define OPER_CONFIG_H_

#define MAX_LINE_LEN 210

char *read_config(FILE *fp, char *key);

int add_config(FILE *fp, char *key, char *value);

#endif

"oper_config.c"

复制代码 代码如下:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include "oper_config.h"

static int check_key(char *line, char *key);

static char *get_value(char *line);

// fp 需要以读的方式得到

char *

read_config(FILE *fp, char *key)

{

 char line[MAX_LINE_LEN] = {'\0'};

 char *value = NULL;

 int ret;

 while(fgets( line, sizeof(line), fp) != NULL)

 {

  ret = check_key(line, key);

  if(ret == -1)

  {

   continue;

  }

  else

  {

   value = get_value(line);

   if(value == NULL)

   {

    del_config(fp, key);

    return NULL;

   }

   else

   {

    return value;

   }

  }

 }/* while */

 return NULL;

}

static int

check_key(char *line, char *key)

{

 char *k_start, *k_end;  // 指示 key 在 line 中的起始和结束位置

 int line_len;

 line_len = strlen(line);

 if(line_len < 3)

 {

  return(-1);

 }

 else

 {

  k_start = &line[0];

  while(((*k_start == ' ') || (*k_start == '\t'))

    && ( k_start <= &line[line_len - 1]))

  {

   k_start ++;

  }

  if(*k_start == '#')

  {

   return(-1);

  }

  k_end = strchr(line, '=');

  if(k_end == NULL)

  {

   return(-1);

  }

  k_end --;

  while(((*k_end == ' ') || (*k_end == '\t'))

    && (k_end >= k_start))

  {

   k_end --;

  }

  if((*k_end == ' ') || (*k_end == '\t'))

  {

   return(-1);

  }

  if(strncmp(key, k_start, k_end-k_start + 1) != 0)

  {

   return(-1);

  }

 }

 return(0);

}/* check_key() */

static char*

get_value(char *line)

{

 char *v_start, *v_end;  // 指示 value 在 line 中的起始和结束位置

 char *value = NULL;

 int line_len;

 int val_len;

 line_len = strlen(line);

 v_start = strchr(line, '='); // 已经在 check_key 中检验过'='的存在

 v_start ++;

 while(((*v_start == ' ') || (*v_start == '\t'))

   && (v_start <= &line[line_len - 1]))

 {

  v_start ++;

 }

 v_end = &line[line_len - 1];

 if(((*v_end == ' ') || (*v_end == '\t')

   || (*v_end == '\n')

   || (*v_end == '\r'))

   && (v_end > v_start))

 {

  v_end --;

 }

 if((*v_end == ' ') || (*v_end == '\t')

   || (*v_end == '\n')

   || (*v_end == '\r'))

 {

  return NULL;

 }

 val_len = v_end - v_start + 1;

 value = (char *)malloc((val_len + 1) * sizeof(char));

 if(value == NULL)

 {

  printf("malloc failed.\n");

  return NULL;

 }

 strncpy(value, v_start, val_len);

 value[val_len] = '\0';

 return value;

}/* get_value() */

// fp 需要以添加的方式得到

int

add_config(FILE *fp, char *key, char *value)

{

 char *line = NULL;

 int key_len;

 int val_len;

 key_len = strlen(key);

 val_len = strlen(value);

 if( (fp == NULL) || (key == NULL) || (value == NULL))

 {

  return(-1);

 }

 line = (char *)malloc((key_len + val_len + 5) * sizeof(char));

 if(line == NULL)

 {

  printf("malloc failed.\n");

  return(-1);

 }

 else

 {

  strncpy(line, key, key_len);

  line[key_len] = ' ';

  line[key_len + 1] = '=';

  line[key_len + 2] = ' ';

  line[key_len + 3] = '\0';

  strncat(line, value, val_len);

  line[key_len + val_len + 3] = '\n';

  line[key_len + val_len + 4] = '\0';

  if(fputs(line, fp) == EOF)

  {

   return(-1);

  }

 }

 free(line);

 return(0);

}/* add_config() */

说明:

1) 配置文件的数据格式  key = value

2) 支持 '#' 开头注释

3) key, value 前后可有空格, tab.

0

精彩评论

暂无评论...
验证码 换一张
取 消