【转】Gtk+读写ini文件
文章转载自:http://blog.chinaunix.net/u/19671/showart.php?id=117843以下两个文件cfgfile.h和cfgfile.c实现了在gtk应用程序中读写ini文件的方法,现贴上源代码,以供参考。
源文件cfgfile.h
#ifndef __CFG_FILE_H__
#define __CFG_FILE_H__
#include <glib.h>
#include <gtk/gtk.h>
#include <time.h>
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 <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#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 = '\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)
{
if (lines == '[')
{
if ((tmp = strchr (lines, ']')))
{
*tmp = '\0';
section =
cfg_file_create_section (cfg,
&lines);
}
}
else if (lines != '#' && section)
{
if ((tmp = strchr (lines, '=')))
{
*tmp = '\0';
tmp++;
cfg_file_create_string (section, lines, 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;
gchar *string;
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=strtok(string,":");
while((p=strtok(NULL,":")))
{ i++;canshu=p; }
color->red=atol(canshu);
color->green=atol(canshu);
color->blue=atol(canshu);
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 <gtk/gtk.h>
#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文件内容:
gtk+=2.9
NO.=89
reg=1
soft=for you
注意:如果ini文件为GB2312编码,那么读取到的字符串将为乱码,请使用g_locale_to_utf8(string,-1,NULL,NULL,NULL);转换就可以了。
当然要保存字符串,请使用g_locale_from_utf8(string,-1,NULL,NULL,NULL); GKeyFile 不就是干这个的吗?为何又要自己实现一个?
页:
[1]