• 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; }
  • 相关阅读:
    STM32与FPGA通信写数据出错问题解决方法
    Altium Designer 8.0不为人知的27个技巧
    modbus详尽中文资料、软件、代码
    STM32中断与NVIC概览
    FatFs读写SD卡出现FR_NO_FILESYSTEM解决方法.
    用两个低位数的DA合成高位数的DA
    4-20mA电流转换电路分析
    C语言写的俄罗斯方块
    无源RS232转RS485(转)
    稻盛和夫写的六项精进指的是什么
  • 原文地址:https://www.cnblogs.com/fuxianfeng1988/p/3292282.html
Copyright © 2020-2023  润新知