void parseconf_load_file(const char *path)//加载配置文件
{
//要加载这个文件首先要打开这个文件
FILE *fp = fopen(path, "r");//以只读的方式打开
if (fp == NULL)//如果等于空指针的话就出错拉
ERR_EXIT("fopen");
char setting_line[1024] = {0};//读取的一行内容保存到这个字符数组中
while (fgets(setting_line, sizeof(setting_line), fp) != NULL)//每当读取到一行时
{
/*从文件结构体指针fp中读取数据,每次读取一行。
* 读取的数据保存在setting_line指向的字符数组中,每次最多读取sizeof(setting_line)个字符(第bufsize个字符赋'\0'),
* 如果文件中的该行,不足sizeof(setting_line)个字符,则读完该行就结束。函数成功将返回setting_line,失败或读到文件结尾返回NULL
*使用fgets() 读取文件的时候bufsize大于该行的字符总数加2
* (多出来的两个,一个保存文件本身的'\n'换行,一个保存字符串本身的结束标识'\0'),
*文件并不会继续读下去,仅仅只是这一行读取完,随后指向文件的指针会自动偏移至下一行
*当第二次再使用这个函数时则会继续随着文件指针读取下一行
* */
if (strlen(setting_line) == 0
|| setting_line[0] == '#'
|| str_all_space(setting_line))
continue;//执行下一循环
str_trim_crlf(setting_line);//去掉哦/r \n,
parseconf_load_setting(setting_line);
memset(setting_line, 0, sizeof(setting_line));//进行清零操作
}
fclose(fp);//一旦遍历完就关闭文件
}
void parseconf_load_setting(const char *setting)//将配置项加载到相应的变量
{
// 去除左空格
while (isspace(*setting)) //判断最前面是否有空格
setting++;//有空格的话指针就向后移
char key[128] ={0};
char value[128] = {0};
str_split(setting, key, value, '=');
if (strlen(value) == 0)
{
fprintf(stderr, "mising value in config file for: %s\n", key);//向错误输出流打印整个信息
exit(EXIT_FAILURE);//退出
}
//下面三种解析代码是类似的,可能有一些差别 // AA=111
//----------------------------解析str_setting---能找到相关关键字的话,就执行下面的下面语句的解析,找不到的话就执行下一种关键字解析---------------------------------------------------------------------------------------
{
const struct parseconf_str_setting *p_str_setting = parseconf_str_array;
//一个二维数组赋值给一个有两个元素的结构体指针, 而这个p_str_setting指针指向的二维数组实际上是数组内层的数组
while (p_str_setting->p_setting_name != NULL)//一直遍历到数组最后,找到关键字就执行下面这些
{
if (strcmp(key, p_str_setting->p_setting_name) == 0) //这里p_setting_name就是listen_address,就是判断key
{
const char **p_cur_setting = p_str_setting->p_variable;
/*p_str_setting->p_variable实际上就是&tunable_listen_address;
实际上就相当于 char p_cur_setting=&tunable_listen_address
下面p_cur_setting=value;
最后还是tunable_listen_address=value;//来赋值
*/
if (*p_cur_setting) //如果已经有数据啦
free((char*)*p_cur_setting);
*p_cur_setting = strdup(value);
return;
}
p_str_setting++;
}
}
// AA=YES AA=TURE AA=1 这种类型的解析
//----------------------解析bool_setting------能找到相关关键字的话,就执行下面的下面语句的解析,找不到的话就执行下一种关键字解析--------------
{
const struct parseconf_bool_setting *p_bool_setting = parseconf_bool_array;
while (p_bool_setting->p_setting_name != NULL)
{
if (strcmp(key, p_bool_setting->p_setting_name) == 0)
{
str_upper(value);//先给他转换成大写
if (strcmp(value, "YES") == 0//=0说明是合法的
|| strcmp(value, "TRUE") == 0
|| strcmp(value, "1") == 0)
*(p_bool_setting->p_variable) = 1;//找到响应的配置项赋值
else if (strcmp(value, "NO") == 0
|| strcmp(value, "FALSE") == 0
|| strcmp(value, "0") == 0)
*(p_bool_setting->p_variable) = 0;
else
{
fprintf(stderr, "bad bool value in config file for: %s\n", key);
exit(EXIT_FAILURE);
}
return;
}
p_bool_setting++;
}
}
//listen_port=21; local_umask=077八进制) 这种类型的解析
//----------------------解析uint_setting-------能找到相关关键字的话,就执行下面的下面语句的解析,找不到的话就执行下一种关键字解析---------------
{
const struct parseconf_uint_setting *p_uint_setting = parseconf_uint_array;
while (p_uint_setting->p_setting_name != NULL)
{
if (strcmp(key, p_uint_setting->p_setting_name) == 0)
{
if (value[0] == '0')//说明是八进制
*(p_uint_setting->p_variable) = str_octal_to_uint(value);
else
*(p_uint_setting->p_variable) = atoi(value);//把字符串转换成整型数
return;
}
p_uint_setting++;
}
}
}
linux网络编程 从配置文件中读取配置并加载到变量中
最新推荐文章于 2024-08-03 19:53:22 发布