C++ 读取写入INI文件

1、适用于C++项目,适用于Windows和Linux平台,依赖STL标准库。

2、用于C++读取INI文件,写入INI文件,以及查找相应键值对的快速操作。

3、在项目中需要此功能时,只需要引入两个文件,即:INIParser.h和INIParser.cpp。

4、main.c文件有例程,同时附带makefile,以及测试使用的conf.ini和生成的test.ini文件。

INIParser.h

01 #ifndef INI_PARSER_H
02 #define INI_PARSER_H
03  
04 #include <iostream>
05 #include <fstream>
06 #include <sstream>
07 #include <vector>
08 #include <cstdlib>
09 #include <map>
10 using namespace std;
11  
12 class ININode
13 {
14 public:
15     ININode(string root, string key, string value)
16     {
17         this->root = root;
18         this->key = key;
19         this->value = value;
20     }
21     string root;
22     string key;
23     string value;
24 };
25  
26 class SubNode
27 {
28 public:
29     void InsertElement(string key, string value)
30     {
31         sub_node.insert(pair<string, string>(key, value));
32     }
33     map<string, string> sub_node;
34 };
35  
36 class INIParser
37 {
38 public:
39     int ReadINI(string path);
40     string GetValue(string root, string key);
41     vector<ININode>::size_type GetSize(){return map_ini.size();}
42     vector<ININode>::size_type SetValue(string root, string key, string value);
43     int WriteINI(string path);
44     void Clear(){map_ini.clear();}
45 private:
46     map<string, SubNode> map_ini;
47 };
48  
49 #endif // INI_PARSER_H

INIParser.cpp

001 #include "INIParser.h"
002  
003 //remove all blank space
004 string &TrimString(string &str)
005 {
006     string::size_type pos = 0;
007     while(str.npos != (pos = str.find(" ")))
008         str = str.replace(pos, pos+1, "");
009     return str;
010 }
011  
012 //read in INI file and parse it
013 int INIParser::ReadINI(string path)
014 {
015     ifstream in_conf_file(path.c_str());
016     if(!in_conf_file) return 0;
017     string str_line = "";
018     string str_root = "";
019     vector<ININode> vec_ini;
020     while(getline(in_conf_file, str_line))
021     {
022         string::size_type left_pos = 0;
023         string::size_type right_pos = 0;
024         string::size_type equal_div_pos = 0;
025         string str_key = "";
026         string str_value = "";
027         if((str_line.npos != (left_pos = str_line.find("["))) && (str_line.npos != (right_pos = str_line.find("]"))))
028         {
029             //cout << str_line.substr(left_pos+1, right_pos-1) << endl;
030             str_root = str_line.substr(left_pos+1, right_pos-1);
031         }
032  
033  
034         if(str_line.npos != (equal_div_pos = str_line.find("=")))
035         {
036            str_key = str_line.substr(0, equal_div_pos);
037            str_value = str_line.substr(equal_div_pos+1, str_line.size()-1);
038            str_key = TrimString(str_key);
039            str_value = TrimString(str_value);
040            //cout << str_key << "=" << str_value << endl;
041         }
042  
043         if((!str_root.empty()) && (!str_key.empty()) && (!str_value.empty()))
044         {
045            ININode ini_node(str_root, str_key, str_value);
046            vec_ini.push_back(ini_node);
047            //cout << vec_ini.size() << endl;
048         }
049     }
050     in_conf_file.close();
051     in_conf_file.clear();
052  
053     //vector convert to map
054     map<string, string> map_tmp;
055     for(vector<ININode>::iterator itr = vec_ini.begin(); itr != vec_ini.end(); ++itr)
056     {
057         map_tmp.insert(pair<string, string>(itr->root, ""));
058     }
059  
060     SubNode sn;
061     for(map<string, string>::iterator itr = map_tmp.begin(); itr != map_tmp.end(); ++itr)
062     {
063        //cout << itr->first << endl;
064        for(vector<ININode>::iterator sub_itr = vec_ini.begin(); sub_itr != vec_ini.end(); ++sub_itr)
065        {
066            if(sub_itr->root == itr->first)
067            {
068                //cout << sub_itr->key << "=" << sub_itr->value << endl;
069                sn.InsertElement(sub_itr->key, sub_itr->value);
070            }
071        }
072        map_ini.insert(pair<string, SubNode>(itr->first, sn));
073     }
074     return 1;
075 }
076  
077 //get value by root and key
078 string INIParser::GetValue(string root, string key)
079 {
080     map<string, SubNode>::iterator itr = map_ini.find(root);
081     map<string, string>::iterator sub_itr = itr->second.sub_node.find(key);
082     if(!(sub_itr->second).empty())
083         return sub_itr->second;
084     return "";
085 }
086  
087 //write ini file
088 int INIParser::WriteINI(string path)
089 {
090     ofstream out_conf_file(path.c_str());
091     if(!out_conf_file)
092         return -1;
093  
094     //cout << map_ini.size() << endl;
095     for(map<string, SubNode>::iterator itr = map_ini.begin(); itr != map_ini.end(); ++itr)
096     {
097        //cout << itr->first << endl;
098        out_conf_file << "[" << itr->first << "]" << endl;
099        for(map<string, string>::iterator sub_itr = itr->second.sub_node.begin(); sub_itr != itr->second.sub_node.end(); ++sub_itr)
100        {
101            //cout << sub_itr->first << "=" << sub_itr->second << endl;
102            out_conf_file << sub_itr->first << "=" << sub_itr->second << endl;
103        }
104     }
105  
106     out_conf_file.close();
107     out_conf_file.clear();
108     return 1;
109 }
110  
111 //set value
112 vector<ININode>::size_type INIParser::SetValue(string root, string key, string value)
113 {
114     map<string, SubNode>::iterator itr = map_ini.find(root);
115     if(map_ini.end() != itr)
116         itr->second.sub_node.insert(pair<string, string>(key, value));
117     else
118     {
119         SubNode sn;
120         sn.InsertElement(key, value);
121         map_ini.insert(pair<string, SubNode>(root, sn));
122     }
123     return map_ini.size();
124 }

测试文件(main.cpp)

01 #include <iostream>
02 #include <fstream>
03 #include <sstream>
04 #include <vector>
05 #include <cstdlib>
06 #include <map>
07 #include "INIParser.h"
08 using namespace std;
09  
10  
11 int main()
12 {
13     INIParser ini_parser;
14     ini_parser.ReadINI("conf.ini");
15     cout << ini_parser.GetValue("default""server_port") << endl;
16     ini_parser.Clear();
17     cout << ini_parser.GetSize() << endl;
18  
19     ini_parser.SetValue("class1","name1","Tom");
20     ini_parser.SetValue("class2","name2","Lucy");
21     ini_parser.WriteINI("test.ini");
22     return 0;
23 }
编译:

1 g++ *.cpp -o test

读取以下INI文件(conf.ini)

1 [default]
2 server_ip = 127.0.0.1
3 server_port = 8800
4  
5 [other]
6 client_num = 10

结果如下:

01 D:\workspace\cpp\INIParser 的目录
02  
03 2014/07/30  09:52    <DIR>          .
04 2014/07/30  09:52    <DIR>          ..
05 2014/07/29  09:20                80 conf.ini
06 2014/07/29  18:43             4,002 INIParser.cpp
07 2014/07/29  18:38             1,012 INIParser.h
08 2014/07/29  18:33               540 main.cpp
09 2014/07/29  18:56               226 makefile
10 2014/07/30  09:52           135,176 test.exe
11 2014/07/29  18:56                39 test.ini
12                7 个文件        141,075 字节
13                2 个目录 96,918,614,016 可用字节
14