linux网络编程 从配置文件中读取配置并加载到变量中

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++;
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值