GTK+中文社区(gtk.awaysoft.com)

 找回密码
 马上加入

QQ登录

只需一步,快速开始

查看: 5310|回复: 1

【转】Gtk+读写ini文件

[复制链接]
  • TA的每日心情
    奋斗
    2021-11-19 13:15
  • 签到天数: 20 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    发表于 2009-4-25 20:04:57 | 显示全部楼层 |阅读模式
    文章转载自:[url:1b0ahsjt]http://blog.chinaunix.net/u/19671/showart.php?id=117843[/url:1b0ahsjt]
    以下两个文件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[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)
            {
                    if (lines[0] == '[')
                    {
                            if ((tmp = strchr (lines, ']')))
                            {
                                    *tmp = '\0';
                                    section =
                                            cfg_file_create_section (cfg,
                                                                   &lines[1]);
                            }
                    }
                    else if (lines[0] != '#' && 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[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=strtok(string,":");
            while((p=strtok(NULL,":")))
            { i++;canshu=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 <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文件内容:

    [system]
    gtk+=2.9
    NO.=89
    reg=1

    [about]
    soft=for you


    注意:如果ini文件为GB2312编码,那么读取到的字符串将为乱码,请使用g_locale_to_utf8(string,-1,NULL,NULL,NULL);转换就可以了。
            当然要保存字符串,请使用g_locale_from_utf8(string,-1,NULL,NULL,NULL);

    该用户从未签到

    发表于 2010-10-21 06:26:00 | 显示全部楼层
    GKeyFile 不就是干这个的吗?为何又要自己实现一个?
    *滑块验证:
    您需要登录后才可以回帖 登录 | 马上加入

    本版积分规则

    申请友链|Archiver|小黑屋|手机版|GTK+中文社区 ( 粤ICP备13080851号 )

    我要啦免费统计

    GMT+8, 2024-12-22 16:57 , Processed in 0.025060 second(s), 8 queries , Redis On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表