Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1426988
  • 博文数量: 430
  • 博客积分: 9995
  • 博客等级: 中将
  • 技术积分: 4388
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-24 18:04
文章存档

2013年(1)

2008年(2)

2007年(14)

2006年(413)

分类:

2006-05-25 11:36:35

以下两个文件cfgfile.h和cfgfile.c实现了在gtk应用程序中读写ini文件的方法,现贴上源代码,以供参考。
源文件cfgfile.h
#ifndef __CFG_FILE_H__
#define __CFG_FILE_H__

#include 
#include 
#include 

typedef struct{
	gchar *key;
	gchar *value;
}ConfigLine;

typedef struct{
	gchar *name;
	GList *lines;
}ConfigSection;

typedef struct{
	GList *sections;
	gchar *cfgfilename;
	gboolean changed;
}ConfigFile;

ConfigFile *cfg_file_new (void);
ConfigFile *cfg_file_open_file (gchar * filename);
gboolean    cfg_file_write_file (ConfigFile * cfg, gchar * filename);
void        cfg_file_free (ConfigFile * cfg);

gboolean cfg_file_read_string (ConfigFile * cfg, gchar * section,gchar * key, gchar ** value);
gboolean cfg_file_read_int (ConfigFile * cfg, gchar * section,gchar * key, gint * value);
gboolean cfg_file_read_long (ConfigFile * cfg, gchar * section,gchar * key, glong * value);
gboolean cfg_file_read_time (ConfigFile * cfg, gchar * section,gchar * key, time_t * value);
gboolean cfg_file_read_boolean (ConfigFile * cfg, gchar * section,gchar * key, gboolean * value);
gboolean cfg_file_read_color (ConfigFile * cfg, gchar * section, gchar * key,GdkColor *color);

void cfg_file_write_string (ConfigFile * cfg, gchar * section,gchar * key, gchar * value);
void cfg_file_write_int (ConfigFile * cfg, gchar * section, gchar * key,gint value);
void cfg_file_write_long (ConfigFile * cfg, gchar * section, gchar * key,glong value);
void cfg_file_write_time (ConfigFile * cfg, gchar * section,gchar * key, time_t value);
void cfg_file_write_boolean (ConfigFile * cfg, gchar * section,gchar * key, gboolean value);
void cfg_file_write_color (ConfigFile * cfg, gchar * section, gchar * key,GdkColor color);

void cfg_file_rename_section (ConfigFile * cfg, gchar * section,gchar * section_name);
void cfg_file_remove_key (ConfigFile * cfg, gchar * section,gchar * key);
void cfg_file_remove_section (ConfigFile * cfg, gchar * section);

#endif
 
源文件cfgfile.c
/*
this file is copy form x11amp,i changed it for some place.
这个文件是我从x11amp(现在叫xmms)拷来的,增删了几个函数.
*/


#include 
#include 
#include 
#include 
#include 
#include 
#include "cfgfile.h"

static ConfigSection *cfg_file_create_section (ConfigFile * cfg, gchar * name);
static ConfigLine    *cfg_file_create_string (ConfigSection * section, gchar * key,gchar * value);
static ConfigSection *cfg_file_find_section (ConfigFile * cfg, gchar * name);
static ConfigLine    *cfg_file_find_string (ConfigSection * section, gchar * key);

ConfigFile* cfg_file_new (void)
{
	ConfigFile *cfg;

	cfg = (ConfigFile *)g_malloc0 (sizeof (ConfigFile));

	return cfg;
}

ConfigFile* cfg_file_open_file (gchar * filename)
{
	ConfigFile *cfg;

	FILE *file;
	gchar *buffer, **lines, *tmp;
	gint i;
	struct stat stats;
	ConfigSection *section = NULL;

	if (stat (filename, &stats) == -1)
		return NULL;
	if (!(file = fopen (filename, "rb")))
		return NULL;

	buffer = (gchar *)g_malloc (stats.st_size + 1);
	fread (buffer, 1, stats.st_size, file);
/*	if (fread (buffer, 1, stats.st_size, file) != stats.st_size)
	{
		g_free (buffer);
		fclose (file);
		return NULL;
	}
*/
	fclose (file);
	buffer[stats.st_size] = '\0';

	cfg = (ConfigFile *)g_malloc0 (sizeof (ConfigFile));
	cfg->cfgfilename = g_strdup (filename);
	cfg->changed = 0;
	lines = g_strsplit (buffer, "\n", 0);
	g_free (buffer);
	i = 0;
	while (lines[i])
	{
		if (lines[i][0] == '[')
		{
			if ((tmp = strchr (lines[i], ']')))
			{
				*tmp = '\0';
				section =
					cfg_file_create_section (cfg,
							       &lines[i][1]);
			}
		}
		else if (lines[i][0] != '#' && section)
		{
			if ((tmp = strchr (lines[i], '=')))
			{
				*tmp = '\0';
				tmp++;
				cfg_file_create_string (section, lines[i], tmp);
			}
		}
		i++;
	}
	g_strfreev (lines);
	return cfg;
}


gboolean cfg_file_write_file (ConfigFile * cfg, gchar * filename)
{
	FILE *file;
	GList *section_list, *line_list;
	ConfigSection *section;
	ConfigLine *line;

	if (!(file = fopen (filename, "wb")))
		return FALSE;

	section_list = cfg->sections;
	while (section_list)
	{
		section = (ConfigSection *) section_list->data;
		if (section->lines)
		{
			fprintf (file, "[%s]\n", section->name);
			line_list = section->lines;
			while (line_list)
			{
				line = (ConfigLine *) line_list->data;
				fprintf (file, "%s=%s\n", line->key,
					 line->value);
				line_list = g_list_next (line_list);
			}
			fprintf (file, "\n");
		}
		section_list = g_list_next (section_list);
	}
	fclose (file);
	return TRUE;
}

gboolean cfg_file_read_string (ConfigFile * cfg, gchar * section, gchar * key,gchar ** value)
{
	ConfigSection *sect;
	ConfigLine *line;

	*value = NULL;
	if (!(sect = cfg_file_find_section (cfg, section)))
		return FALSE;
	if (!(line = cfg_file_find_string (sect, key)))
		return FALSE;
	*value = g_strdup (line->value);
	return TRUE;
}

gboolean cfg_file_read_int (ConfigFile * cfg, gchar * section, gchar * key, gint * value)
{
	gchar *str;

	if (!cfg_file_read_string (cfg, section, key, &str))
	{
		*value = 0;
		return FALSE;
	}
	*value = atoi (str);
	g_free (str);

	return TRUE;
}

gboolean cfg_file_read_long (ConfigFile * cfg, gchar * section, gchar * key, glong * value)
{
	gchar *str;

	if (!cfg_file_read_string (cfg, section, key, &str))
	{
		*value = 0;
		return FALSE;
	}
	*value = atol (str);
	g_free (str);

	return TRUE;
}

gboolean cfg_file_read_time (ConfigFile * cfg, gchar * section, gchar * key,time_t * value)
{
	gchar *str;

	if (!cfg_file_read_string (cfg, section, key, &str))
	{
		*value = 0;
		return FALSE;
	}
	*value = atol (str);
	g_free (str);

	return TRUE;
}

gboolean cfg_file_read_boolean (ConfigFile * cfg, gchar * section, gchar * key,gboolean * value)
{
	gchar *str;

	if (!cfg_file_read_string (cfg, section, key, &str))
	{
		*value = FALSE;
		return FALSE;
	}
	if (!strcmp (str, "0"))
		*value = FALSE;
	else
		*value = TRUE;	//gtk_widget_modify_base(sd->mainwin->textview,GTK_STATE_NORMAL,&sd->conf.bgcolor);

	g_free (str);
	return TRUE;
}

gboolean cfg_file_read_color (ConfigFile * cfg, gchar * section, gchar * key,GdkColor *color)
/*this was added by yetist */
{
	gchar *str;
	gchar *p;
	gchar *canshu[3];
	gchar *string[80];
	gint i=0;
	if (!cfg_file_read_string (cfg, section, key, &str))
	{
		color->pixel=0;
		color->red=0;
		color->green=0;
		color->blue=0;
		return FALSE;
	}	
	strcpy(string,str);
	canshu[i]=strtok(string,":");
	while((p=strtok(NULL,":")))
	{ i++;canshu[i]=p; }
 	color->red=atol(canshu[0]);
	color->green=atol(canshu[1]);
	color->blue=atol(canshu[2]);
	return TRUE;
}

void cfg_file_write_string (ConfigFile * cfg, gchar * section, gchar * key,gchar * value)
{
	ConfigSection *sect;
	ConfigLine *line;

	cfg->changed = 1;
	sect = cfg_file_find_section (cfg, section);
	if (!sect)
		sect = cfg_file_create_section (cfg, section);
	if ((line = cfg_file_find_string (sect, key)))
	{
		g_free (line->value);
		line->value = g_strchug (g_strchomp (g_strdup (value)));
	}
	else
		cfg_file_create_string (sect, key, value);
}

void cfg_file_write_int (ConfigFile * cfg, gchar * section, gchar * key, gint value)
{
	gchar *strvalue;
	strvalue = g_strdup_printf ("%d", value);
	cfg_file_write_string (cfg, section, key, strvalue);
	g_free (strvalue);
}

void cfg_file_write_long (ConfigFile * cfg, gchar * section, gchar * key, glong value)
{
	gchar *strvalue;
	strvalue = g_strdup_printf ("%ld", value);
	cfg_file_write_string (cfg, section, key, strvalue);
	g_free (strvalue);
}

void cfg_file_write_time (ConfigFile * cfg, gchar * section, gchar * key,time_t value)
{
	gchar *strvalue;
	strvalue = g_strdup_printf ("%ld", value);
	cfg_file_write_string (cfg, section, key, strvalue);
	g_free (strvalue);
}

void cfg_file_write_boolean (ConfigFile * cfg, gchar * section, gchar * key,gboolean value)
{
	if (value)
		cfg_file_write_string (cfg, section, key, "1");
	else
		cfg_file_write_string (cfg, section, key, "0");
}

void cfg_file_write_color (ConfigFile * cfg, gchar * section, gchar * key,GdkColor color)
/*this was added by yetist */
{
	gchar *strvalue;
	strvalue = g_strdup_printf ("%u:%u:%u", color.red, color.green, color.blue);
	cfg_file_write_string (cfg, section, key, strvalue);
	g_free (strvalue);
}





void cfg_file_rename_section (ConfigFile * cfg, gchar * section,gchar * section_name)
{
	ConfigSection *sect;

	sect = cfg_file_find_section (cfg, section);
	if (sect)
	{
		cfg->changed = 1;
		g_free (sect->name);
		sect->name = g_strdup (section_name);
	}
}

void cfg_file_remove_key (ConfigFile * cfg, gchar * section, gchar * key)
{
	ConfigSection *sect;
	ConfigLine *line;

	sect = cfg_file_find_section (cfg, section);
	if (sect)
	{
		line = cfg_file_find_string (sect, key);
		if (line)
		{
			cfg->changed = 1;
			g_free (line->key);
			g_free (line->value);
			g_free (line);
			sect->lines = g_list_remove (sect->lines, line);
		}
	}
}

void cfg_file_remove_section (ConfigFile * cfg, gchar * section)	/* this was added by me 我加的,应该没错误 */
{
	ConfigSection *sect;
	ConfigLine *line;
	GList *line_list;

	sect = cfg_file_find_section (cfg, section);
	if (sect)
	{
		cfg->changed = 1;
		g_free (sect->name);
		line_list = sect->lines;
		while (line_list)
		{
			line = (ConfigLine *) line_list->data;
			g_free (line->key);
			g_free (line->value);
			g_free (line);
			line_list = g_list_next (line_list);
		}
		g_list_free (sect->lines);
		g_free (sect);
		cfg->sections = g_list_remove (cfg->sections, sect);
	}
}


void cfg_file_free (ConfigFile * cfg)
{
	ConfigSection *section;
	ConfigLine *line;
	GList *section_list, *line_list;

	g_free (cfg->cfgfilename);
	section_list = cfg->sections;
	while (section_list)
	{
		section = (ConfigSection *) section_list->data;
		g_free (section->name);

		line_list = section->lines;
		while (line_list)
		{
			line = (ConfigLine *) line_list->data;
			g_free (line->key);
			g_free (line->value);
			g_free (line);
			line_list = g_list_next (line_list);
		}
		g_list_free (section->lines);
		g_free (section);

		section_list = g_list_next (section_list);
	}
	g_list_free (cfg->sections);
	cfg->sections = NULL;	/*这两行我加的,cfg_file_free后可回到cfg_file_new状态,可继续使用. */
	cfg->cfgfilename = NULL;
}

static ConfigSection * cfg_file_create_section (ConfigFile * cfg, gchar * name)
{
	ConfigSection *section;
	section = (ConfigSection *)g_malloc0 (sizeof (ConfigSection));
	section->name = g_strdup (name);
	cfg->sections = g_list_append (cfg->sections, section);

	return section;
}

static ConfigLine * cfg_file_create_string (ConfigSection * section, gchar * key, gchar * value)
{
	ConfigLine *line;
	line = (ConfigLine *)g_malloc0 (sizeof (ConfigLine));
	line->key = g_strchug (g_strchomp (g_strdup (key)));
	line->value = g_strchug (g_strchomp (g_strdup (value)));
	section->lines = g_list_append (section->lines, line);

	return line;
}

static ConfigSection * cfg_file_find_section (ConfigFile * cfg, gchar * name)
{
	ConfigSection *section;
	GList *list;

	list = cfg->sections;
	while (list)
	{
		section = (ConfigSection *) list->data;
		if (!strcasecmp (section->name, name))
			return section;
		list = g_list_next (list);
	}
	return NULL;
}

static ConfigLine * cfg_file_find_string (ConfigSection * section, gchar * key)
{
	ConfigLine *line;
	GList *list;

	list = section->lines;
	while (list)
	{
		line = (ConfigLine *) list->data;
		if (!strcasecmp (line->key, key))
			return line;
		list = g_list_next (list);
	}
	return NULL;
}
 
用法示例(main.c):
#include 
#include "cfgfile.h"

void on_button_clicked(GtkButton *button,gpointer data)
{
	ConfigFile *ini;
	ini=cfg_file_new();
	cfg_file_write_string(ini,"system","gtk+","2.9");
	cfg_file_write_int(ini,"system","NO.",89);
	cfg_file_write_boolean(ini,"system","reg","TRUE");
	cfg_file_write_string(ini,"about","soft","for you");
	cfg_file_write_file(ini,"test.ini");
	cfg_file_free(ini);
}

int main(int argc,char* argv[])
{
	GtkWidget *window;
	GtkWidget *button;
	gtk_init(&argc,&argv);
	window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
	g_signal_connect(G_OBJECT(window),"delete_event",G_CALLBACK(gtk_main_quit),NULL);
	gtk_window_set_title(GTK_WINDOW(window),"use ini file");
	gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
	gtk_container_set_border_width(GTK_CONTAINER(window),20);
	button=gtk_button_new_with_label("click me");
	g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(on_button_clicked),NULL);
	gtk_container_add(GTK_CONTAINER(window),button);
	gtk_widget_show_all(window);
	gtk_main();
	return 0;
}
 
test.ini文件内容:
[system]
gtk+=2.9
NO.=89
reg=1

[about]
soft=for you
阅读(2151) | 评论(2) | 转发(0) |
0

上一篇:GDK 事件类型

下一篇:intltool-0.25

给主人留下些什么吧!~~