zoukankan      html  css  js  c++  java
  • ini文件的读写

    题目: INI文件操作库

    INI文件就是扩展名为“ini”的文件。在Windows系统中,INI文件很多,最重要的就是“System.ini”、 “System32.ini”和“Win.ini”。该文件主要存放用户所做的选择以及系统的各种参数。用户可以通过修改INI文件,来改变应用程序和系统的很多配置。


        首先,我们先来了解下INI文件的结构。INI文件是一种按照特定方式排列的文本文件。每一个INI文件构成都非常类似,由若干段落(section)组成。在每个段落下面,是若干个以单个单词开头的关键词(key)和一个等号,等号右边的就是关键字对应的值(value)。即一般形式如下:

    [Section1]
    KeyWord1 = Valuel
    KeyWord2 = Value2

    [gmy_p]

    exist_p=0

    linux_p=123

    其中[gmy_p]为section;exist_p为key;0为key的值value。

    在本题中我们假设INI文件的结构中没有section部分,即我们所定义的inifile文件结构如下: 

    Key1 = Valuel                

    Key2 = Value2

    我们需要实现一个能对inifile文件进行读写操作的库。该库通过包含inifile.h来调用。读操作中需要将文件中每行的key值和其对应的value值读出;写操作中需要将给定的key和value值按照inifile文件的结构写入文件中。

    下面给出inifile.h中函数原型

    int load(char * filename); #装载正常返回0

    int read(char * section, char * key, char * stored_value);

    int write(char * section, char * key, char * value_write);

    需要写的程序:

    (1)    在inifile.c中实现三个函数

    (2)    写一个示例程序,看看infile这个库能不能正常工作。

    提示:

    由于不知道inifile中有多少个section和多少个value,所以需要用到链表来存储。

    #####main.c#########
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include "inifile.h"
    
    int main(void)
    {   
        int result;
        inifile_dest_t ifd;
        char *section, *key, *wvalue;
        char value[MAX_VALUE_LEN];
    
        memset(&ifd, 0, sizeof(inifile_dest_t));//将ifd中前sizeof(inifile_dest_t)个字节用 0 替换并返回ifd 。
    
        /* 加载ini文件 */
        result = load_ini(&ifd, "system.ini");
        if (result != 0) {
            
        }
    
        /* 显示ini文件内容 */
        //show_inifile_info(&ifd);
    
        /* 读取ini文件key的值 */
        memset(value, 0, MAX_VALUE_LEN);
        section = "drivers";
        key = "timer";
        result = read_ini(&ifd, section, key, value, MAX_VALUE_LEN);
        if (result != 0) {
            close_ini(&ifd);
            return -1;
        }
        printf("read inifile info:
    ");
        printf("section: %s
    ", section);
        printf("key    : %s
    ", key);
        printf("value  : %s
    ",value);
    
        /* 设置ini文件key的值 */
        section = "drivers";
        key = "timer";
        wvalue = "qingtian";
        result = write_ini(&ifd, section, key, wvalue);
        if (result != 0) {
            close_ini(&ifd);
            return -1;
        }
        printf("write inifile info:
    ");
        printf("section: %s
    ", section);
        printf("key    : %s
    ", key);
        printf("value  : %s
    ", wvalue);
    
        /* 关闭已经打开的ini文件,释放资源 */
        close_ini(&ifd);
    
        return 0;
    }

    ################inifile.h############# #ifndef _INIFILE_H_
    #define _INIFILE_H_ #define MAX_SECTION_LEN 128 /* 最大section长度 */ #define MAX_KEY_LEN 128 /* 最大kye长度 */ #define MAX_VALUE_LEN 128 /* 最大value长度 */ #define MAX_BUFFER_LEN 128 /* 最大缓冲区长度 */ #define TRUE 1 #define FALSE 0 typedef struct section_enty_s { char *section; /* section name */ char *key; /* key */ char *value; /* key value */ struct section_enty_s *next; } section_enty_t; typedef struct inifile_dest_s { char *filename; /* open ini file name */ struct section_enty_s *enty; } inifile_dest_t; /* 读取ini文件,把文件信息保存到文件描述符句柄中 */ extern int load_ini(inifile_dest_t *ifd, char *filename); /* 根据描述符句柄,读取key对应的值 */ extern int read_ini(inifile_dest_t *ifd, const char *section, const char *key, char *stored_value, int vlen); /* 设置对应key的value值 */ extern int write_ini(inifile_dest_t *ifd, const char *section, const char *key, char *value_write); /* 显示ini文件信息 */ extern void show_inifile_info(inifile_dest_t *ifd); /* 关闭ini文件, 如果句柄有执行过write操作,将对应的key的值写回到文件中 */ extern int close_ini(inifile_dest_t *ifd); #endif /* _INIFILE_H_ */
    #################inifile.c###################




    #include <stdio.h> #include <stdlib.h> #include <string.h> #include "inifile.h" /* 释放section节点 */ static void free_sect_enty(section_enty_t *enty) { if (enty->section != NULL) { free(enty->section); } if (enty->key != NULL) { free(enty->key); } if (enty->value!= NULL) { free(enty->value); } free(enty); } /* 释放已经加载的ini文件 */ static void free_inifile_dest_enty(inifile_dest_t *ifd) { section_enty_t *tmp, *p; tmp = ifd->enty; while (tmp != NULL) { p = tmp->next; free_sect_enty(tmp); tmp = p; } } /* 显示ini文件内容信息 */ void show_inifile_info(inifile_dest_t *ifd) { section_enty_t *enty; if (ifd == NULL) { return; } printf("inifile name:%s ", ifd->filename); enty = ifd->enty; while (enty != NULL) { printf("section:%s ", enty->section); printf("key :%s ", enty->key); printf("value :%s ", enty->value); enty = enty->next; } } /* 往inifile句柄中添加一section节点 */ static void add_section_to_ifd(inifile_dest_t *ifd, section_enty_t *enty) { enty->next = ifd->enty; ifd->enty = enty; } /* 更新值到ini文件中 */ static int write_info_back_inifile(inifile_dest_t *ifd, section_enty_t *enty) { FILE *input, *output; char buf[MAX_BUFFER_LEN]; char *ch, *tmp, *tmp_file; int filename_len, wflags; /* 为临时文件添加"_tmp"文件名 */ filename_len = strlen(ifd->filename); tmp_file = (char *)malloc(filename_len + 5); //新建文件名为"system.ini_tmp",所以加4+1(结束符'') if (tmp_file == NULL) { printf("no enough memory! "); } sprintf(tmp_file, "%s%s", ifd->filename, "_tmp"); //第一个参数是字符缓冲区,保存格式转换后的字符串;第二个是格式字符串 input = fopen(ifd->filename, "r"); //"r"模式下该文件必须存在 if (input == NULL) { return -1; } output = fopen(tmp_file, "w"); //"w"模式下若文件不存在则建立文件 if (output == NULL) { return -1; } while ((ch = fgets(buf, MAX_BUFFER_LEN, input)) != NULL) //失败或读到文件结尾时返回NULL { if (strstr(buf, enty->section) != NULL) //从字符串buf中查找是否有字符串enty->section,若有则返回enty->section在buf中的起始位置的指针,否则,返回NULL { wflags = 1; fprintf(output, "%s", buf); //int fprintf(FILE *stream,char *format,[argument]),其作用是格式化输出到一个流/文件中 continue; //fprintf()函数根据指定的format(格式)发送信息(参数)到由stream(流)指定的文件. f } if ( strstr(buf, enty->key) != NULL) { tmp = strchr(buf, '='); //对比函数strstr if (tmp != NULL) { tmp++; strcpy(tmp, enty->value); wflags = 0; fprintf(output, "%s ", buf); continue; } } fprintf(output, "%s", buf); } fclose(input); fclose(output); /* 修改临时文件名 */ (void)remove(ifd->filename); //int remove(const char *filename),删除一个文件 (void)rename(tmp_file, ifd->filename); //int rename(char *oldname, char *newname);给一个文件重命名 free(tmp_file); return 0; } /** * load_ini - 读取ini文件,把文件信息保存到文件描述符句柄中 * @ifd : ini文件句柄描述符指针 * @filename: 文件名 */ int load_ini(inifile_dest_t *ifd, char *filename) { FILE *input; int buflen, sect_len; //sect_flag; char buf[MAX_BUFFER_LEN]; char sect[MAX_SECTION_LEN]; char *ch, *tmp; char *begin, *end; section_enty_t *enty; if (ifd == NULL || filename == NULL) { return -1; } /* 将文件名称保存到句柄中 */ ifd->filename = (char *)malloc(strlen(filename)); if (ifd->filename == NULL) { return -1; } strcpy(ifd->filename, filename); //extern char *strcpy(char* dest, const char *src) input = fopen(filename, "r"); if (input == NULL) { printf("open ini file error! "); return -1; } /* read a line from file buffer */ memset(buf, 0, MAX_BUFFER_LEN); memset(sect, 0, MAX_SECTION_LEN); //sect_len = sect_flag = 0; while ((ch = fgets(buf, MAX_BUFFER_LEN, input)) != NULL) //char *fgets(char *buf, int bufsize, FILE *stream); { begin = buf; /* 删除头部的空格 */ while(*begin == ' ') { begin++; } if (*begin == ' ' || *begin == ';') { continue; } tmp = strchr(buf, '['); //找字符串buf中首次出现字符'['的位置 if (tmp != NULL) { begin = tmp + 1; end = strchr(begin, ']'); if (end == NULL) { printf("the inifile is damaged! "); continue; } /* 拷贝字符串内容到sect数组 */ sect_len = end - begin; strncpy(sect, begin, sect_len);//复制begin中的前sect_len字节的内容到sect continue; } /* 处理key与对应的value字段 */ if ((tmp = strchr(buf, '=')) != NULL) { enty = (section_enty_t *)malloc(sizeof(section_enty_t)); if (enty == NULL) { printf("malloc section enty error! "); fclose(input); free_inifile_dest_enty(ifd); return -1; } enty->section = (char *)malloc(sect_len+1*sizeof(char));//section长度再加上结束符'' if (enty->section == NULL) { printf("malloc section buffer error! "); free(enty); fclose(input); free_inifile_dest_enty(ifd); return -1; } strncpy(enty->section, sect, sect_len); *(enty->section+sect_len)=''; /* 处理key内容 */ buflen = tmp - begin; enty->key = (char *)malloc(buflen+1*sizeof(char)); if (enty->key == NULL) { printf("malloc key buffer error! "); free(enty->section); free(enty); fclose(input); free_inifile_dest_enty(ifd); return -1; } strncpy(enty->key, begin, buflen); *(enty->key+buflen)=''; /* 处理value内容 */ end = tmp++; while (*end != '' && *end != ' ') { end++; } buflen = end - tmp; enty->value = (char *)malloc(buflen+1*sizeof(char)); if (enty->value == NULL) { printf("malloc value buffer error! "); free(enty->section); free(enty->key); free(enty); fclose(input); free_inifile_dest_enty(ifd); return -1; } strncpy(enty->value, tmp, buflen); *(enty->value+buflen)=''; /* 配置信息挂到inifile句柄中 */ add_section_to_ifd(ifd, enty); } } fclose(input); return 0; } /** * read_ini - 根据描述符句柄,读取key对应的值 * @ifd : inifile句柄描述符 * @section: 段值 * @key : key值 * @stored_value: 存储ini文件中的key对应的值 * @vlen : 保存value值空间的长度 */ int read_ini(inifile_dest_t *ifd, const char *section, const char *key, char *stored_value, int vlen) { section_enty_t *enty, *tmp; if (ifd == NULL || section == NULL || key == NULL || stored_value == NULL) { return -1; } tmp = ifd->enty; while (tmp != NULL) { enty = tmp; if ((strcmp(enty->section, section) == 0) && (strcmp(enty->key, key) == 0)) { strncpy(stored_value, enty->value, vlen); break; } tmp = tmp->next; } return 0; } /** * write_ini - 设置对应key的value值 * @ifd : inifile句柄描述符 * @section: 段值 * @key : key值 * @value_write: 设置key对应的值 */ int write_ini(inifile_dest_t *ifd, const char *section, const char *key, char *value_write) { section_enty_t *enty, *tmp; char *ch; int vlen; if (ifd == NULL || section == NULL || key == NULL || value_write == NULL) { return -1; } tmp = ifd->enty; while (tmp != NULL) { enty = tmp; if ((strcmp(enty->section, section) == 0) && (strcmp(enty->key, key) == 0)) { vlen = strlen(value_write); ch = (char *)malloc(vlen+1*sizeof(char)); if (ch == NULL) { printf("malloc value error! "); return -1; } free(enty->value); enty->value = ch; strncpy(enty->value, value_write, vlen); *(enty->value+vlen)=''; write_info_back_inifile(ifd, enty); break; } tmp = tmp->next; } return 0; } /* 关闭ini文件, 如果句柄有执行过write操作,将对应的key的值写回到文件中 */ int close_ini(inifile_dest_t *ifd) { if (ifd == NULL) { return -1; } free_inifile_dest_enty(ifd); return 0; }
  • 相关阅读:
    关于在MAC上进行 LARAVEL 环境 Homestead 安装过程记录
    js 贷款计算器
    js 实现阶乘
    js 两点间距离函数
    composer Your requirements could not be resolved to an installable set of packages
    vue 项目优化记录 持续更新...
    vue 项目打包
    vue 真机调试页面出现空白
    vue 真机调试
    谈谈-Android状态栏的编辑
  • 原文地址:https://www.cnblogs.com/fuxianfeng1988/p/3292282.html
Copyright © 2011-2022 走看看