INI格式:
cpp
[server]
ip = 127.0.0.1
port = 80
[profile]
name = jack
gender = male
age = 30
IniFile.h
cpp
#pragma once
#include <string>
#include <map>
class Value {
public:
Value();
explicit Value(bool value);
explicit Value(int value);
explicit Value(double value);
explicit Value(const char * value);
explicit Value(const std::string & value);
Value& operator = (bool value);
Value& operator = (int value);
Value& operator = (double value);
Value& operator = (const char * value);
Value& operator = (const std::string & value);
explicit operator bool();
explicit operator int();
explicit operator double();
explicit operator std::string();
private:
std::string m_value;
};
typedef std::map<std::string, Value> Section;
class IniFile {
public:
IniFile();
bool load(const std::string & filename);
Value & get(const std::string & section, const std::string & key);
void set(const std::string & section, const std::string & key,const Value & value);
bool has(const std::string & section,const std::string & key);
bool has(const std::string & secton);
void remove(const std::string & section,const std::string & key);
void remove(const std::string & section);
void clear();
bool save(const std::string& filename);
Section & operator [] (const std::string & section) {
return m_sections[section];
}
private:
std::string trim(std::string & str);
private:
std::string m_filename;
std::map<std::string,Section> m_sections;
};
IniFile.cpp
cpp
#include "IniFile.h"
#include <fstream>
#include <iostream>
Value::Value() {
m_value = "";
}
Value::Value(bool value) {
*this = value;
}
Value::Value(int value) {
*this = value;
}
Value::Value(double value) {
*this = value;
}
Value::Value(const char * value) {
*this = value;
}
Value::Value(const std::string & value) {
*this = value;
}
Value& Value::operator=(bool value) {
m_value = value ? "true" : "false";
return *this;
}
Value& Value::operator=(int value) {
m_value = std::to_string(value);
return *this;
}
Value& Value::operator=(double value) {
m_value = std::to_string(value);
return *this;
}
Value& Value::operator=(const char* value) {
m_value = value;
return *this;
}
Value& Value::operator=(const std::string& value) {
m_value = value;
return *this;
}
Value::operator bool() {
return m_value == "true";
}
Value::operator int() {
return std::stoi(m_value);
}
Value::operator double() {
return std::stod(m_value);
}
Value::operator std::string() {
return m_value;
}
IniFile::IniFile() = default;
bool IniFile::load(const std::string & filename) {
m_filename = filename;
std::ifstream fin( filename);
if(fin.fail()) {
std::cout << "Failed to open file: " <<std::endl;
return false;
}
std::string line;
std::string section;
while(std::getline(fin, line)) {
line = trim(line);
if(line.empty()) {
continue;
}
int pos = line.find_first_of(']');
if(pos != std::string::npos) {
section = line.substr(1, pos - 1);
section = trim(section);
m_sections[section] = Section();
}else {
int pos = line.find_first_of('=');
if(pos != std::string::npos) {
std::string key = line.substr(0, pos);
key = trim(key);
std::string value = line.substr(pos + 1);
value = trim(value);
m_sections[section][key] = value;
}
}
}
fin.close();
return true;
}
std::string IniFile::trim(std::string &str) {
if(str.empty()) {
return str;
}
str.erase(0, str.find_first_not_of(" \n\r"));
str.erase(str.find_last_not_of(" \n\r") + 1);
return str;
}
Value & IniFile::get(const std::string & section, const std::string & key) {
return m_sections[section][key];
}
void IniFile::set(const std::string & section, const std::string & key,const Value & value) {
m_sections[section][key] = value;
}
bool IniFile::has(const std::string & section,const std::string & key) {
std::map<std::string,Section>::const_iterator it = m_sections.find(section);
if(it != m_sections.end()) {
return it->second.find(key) != it->second.end();
}
return false;
}
// 在 IniFile 类中添加保存方法
bool IniFile::save(const std::string& filename) {
std::ofstream fout(filename );
if (fout.fail()) {
return false;
}
for ( auto& section_pair : m_sections) {
fout << "[" << section_pair.first << "]\n";
for ( auto& key_value : section_pair.second) {
fout << key_value.first << "=" << static_cast<std::string>(key_value.second) << "\n";
}
fout << "\n";
}
fout.close();
return true;
}
bool IniFile::has(const std::string & section) {
return m_sections.find(section) != m_sections.end();
}
void IniFile::remove(const std::string & section,const std::string & key) {
std::map<std::string,Section>::iterator it = m_sections.find(section);
if(it != m_sections.end()) {
it->second.erase(key);
}
}
void IniFile::remove(const std::string & section) {
m_sections.erase(section);
}
void IniFile::clear() {
m_sections.clear();
}
main.cpp
cpp
#include <iostream>
#include "IniFile.h"
int main() {
IniFile ini;
ini.load("test.ini");
const std::string & ip = static_cast<std::string>(ini.get("server", "ip"));
int port = static_cast< int>(ini.get("server", "port"));
std::cout<<"ip:"<<ip<<" port:"<<port<<std::endl;
const std::string ipp = static_cast<std::string>(ini["server"]["ip"]);
std::cout<<"ipp:"<<ipp<<std::endl;
//ini.set("server", "ip", "192.168.1.1");
//std::cout<<"ip:"<<ip<<" port:"<<port<<std::endl;
ini.set("server","timeout",Value(1000));
std::cout<<"timeout:"<<static_cast<int>(ini.get("server","timeout"))<<std::endl;
bool b = ini.has("server","timeout");
std::cout<<"has timeout:"<<b<<std::endl;
b = ini.has("server");
std::cout<<"has server:"<<b<<std::endl;
ini.remove("server","timeout");
ini.save("test.ini");
return 0;
}