小的ini解析器,缩进…… ini_parser.cpp /** * 作者: 王政杰 * 日期: 2011.3.16 * 功能描述: ini文件解析器的具体实现 * 可以读取文件,并装入map结构中,供用户调用。 * * 存储方式,section == map<string ,key> * key == map<string ,string> */ #include "ini_parser.h" namespace my_ini { static const char left_tag = '['; static const char right_tag = ']'; static const char equal = '='; static const char cr = '/r'; static const char new_line = '/n'; static const char* empty_str = " "; static const char comment_tag = ';'; ini_parser::ini_parser () : m_modified(false) { } ini_parser::ini_parser (const char* file_name) : m_modified(false) { load(file_name); } ini_parser::~ini_parser () { if (m_modified) save(); } void ini_parser::save_before_load() { if (m_modified) save(); m_file_name.resize(0); m_section.clear(); m_modified = false; } /* *读取 文件file_name * * */ bool ini_parser::load(const char* file_name) { save_before_load (); ifstream in_file (file_name); if (in_file == NULL) { return false; } in_file.seekg (0, ios::end);/* *file.seekg(0,ios::beg); // 让文件指针定位到文件开头 *file.seekg(0,ios::end); // 让文件指针定位到文件末尾 *file.seekg(10,ios::cur); // 让文件指针从当前位置向文件末方向移动10个字节 *file.seekg(-10,ios::cur); // 让文件指针从当前位置向文件开始方向移动10个字节 *file.seekg(10,ios::beg); // 让文件指针定位到离文件开头10个字节的位置 */ long len = in_file.tellg(); if (len < 0) { return false; } char* buffer = new char[len + 1]; for(int i = 0; i<= len; i++) { buffer[i] = 0; } if (buffer == NULL) { return false; } in_file.seekg(0, ios::beg); in_file.read(buffer, len); buffer[len = in_file.gcount()] = 0; //gcount() 用于统计读入的字节数 load_into_section (buffer, len); m_file_name = file_name; delete[] buffer; return true; } /* *对缓冲区内容进行解析,并存入map中 * * */ bool ini_parser::load_into_section (const char* buffer, long len) { const char* p = NULL; const char* key_begin = NULL; const char* section_begin = NULL; const char* value_begin = NULL; const char* comment_begin = NULL; string comment; string sec; string key; enum _STATUS{ STAT_NONE, STAT_SECTION, STAT_KEY, STAT_VALUE, STAT_COMMENT }state = STAT_NONE; for( p = buffer; *p != 0; p++) { switch( state ) { case STAT_NONE: { if( *p == left_tag) { state = STAT_SECTION; section_begin = p + 1; } else if( *p == comment_tag) { state = STAT_COMMENT; comment_begin = p + 1; } else if( !isspace(*p)) { state = STAT_KEY; key_begin = p; } break; } case STAT_SECTION: { if ( *p == right_tag) { state = STAT_NONE; sec = string(section_begin, p - section_begin); strtrim (sec); } break; } case STAT_KEY: { if ( *p == equal ) { state = STAT_VALUE; key = string(key_begin, p - key_begin); strtrim(key); value_begin = p+1; } break; } case STAT_VALUE: { if ( *p == new_line || *p == cr) { state = STAT_NONE; m_section[sec][key] = string(value_begin, p - value_begin); //m_section[sec] = key_value(key, string(value_begin, p - value_begin)); } break; } case STAT_COMMENT: { if ( *p == new_line || *p == cr) { state = STAT_NONE; comment = string(comment_begin, p - comment_begin); strtrim( comment ); m_comment.push_back( comment ); } break; } } } return 0; } /* * 去除字符串首尾的空格 * * */ string ini_parser::strtrim (string &str) { str.erase(str.find_last_not_of(" ")+1); str.erase(0,str.find_first_not_of(" ")); return str; } bool ini_parser::save() { if(0 == m_file_name.c_str() || 0 == m_file_name[0]) { return false; } ofstream out_file(m_file_name.c_str()); if(!out_file) { return false; } for(section_iterator it_section = m_section.begin(); it_section != m_section.end(); it_section ++) { out_file << left_tag << it_section->first << right_tag << endl; for( key_iterator it_key = it_section->second.begin(); it_key != it_section->second.end(); it_key ++) { out_file << it_key->first << equal << it_key->second << endl; } out_file << endl; } m_modified = false; } /* * *获取 某个section 某个key 所对应的值 * */ const char* ini_parser::get_key_value(const char* sec, const char* key) { section_iterator it_section = m_section.find(sec); if(m_section.end() != it_section) { key_iterator it_key = it_section->second.find(key); if(it_key != it_section->second.end()) return it_key->second.c_str(); } return 0; } /* * *修改 某个section 某个key所对应的值 * */ void ini_parser::set_string(const char* sec, const char* key, const char* value) { m_section[sec][key] = value; m_modified = true; } /* * *以int类型来读取 * */ int ini_parser::get_int(const char* sec, const char* key, int def_val) { istrstream( get_key_value(sec, key)) >> def_val; return def_val; } /* * *以float类型来读取 * */ float ini_parser::get_float(const char* sec, const char* key, float def_val) { istrstream(get_key_value(sec, key)) >> def_val; return def_val; } string ini_parser::get_string (const char* sec, const char* key) { return get_key_value(sec, key); } void ini_parser::set_int(const char* sec, const char* key, int value) { char buffer[BUFFER_LEN + 1] = {0}; ostrstream ostr(buffer, BUFFER_LEN); ostr << value; buffer[ostr.pcount()] = 0; set_string(sec, key, buffer); } void ini_parser::set_float(const char* sec, const char* key, float value) { char buffer[BUFFER_LEN + 1] = {0}; ostrstream ostr(buffer, BUFFER_LEN); ostr << value; set_string(sec, key, buffer); } } ini_parser.h /** * 作者: 王政杰 * 日期: 2011.3.16 * 功能描述: ini文件解析器的具体实现 * 可以读取文件,并装入map结构中,供用户调用。 * * * */ #ifndef INI_PARSER_H #define INI_PARSER_H #include <map> #include <vector> #include <string> #include <fstream> #include <strstream> using namespace std; #define BUFFER_LEN 255 namespace my_ini{ class ini_parser { public: typedef std::map<std::string, std::string> key_value; typedef std::map<std::string, key_value> section; typedef key_value::iterator key_iterator; typedef section::iterator section_iterator; typedef vector<std::string> comment; public: ini_parser (); ini_parser (const char* file_name); ~ini_parser (); void save_before_load (); bool load_into_section (const char* buffer, long len); bool load (const char* file_name); bool save (); bool isModified () const { return m_modified; } string strtrim (string & str); public: const char* get_key_value(const char* sec, const char* key); int get_int (const char* sec, const char* key, int def_val); float get_float (const char* sec, const char* key, float def_val); string get_string (const char* sec, const char* key); void set_int (const char* sec, const char* key, int value); void set_float (const char* sec, const char* key, float value); void set_string (const char* sec, const char* key, const char* value); private: bool m_modified; section m_section; std::string m_file_name; comment m_comment; }; } #endif 欢迎留言批评!谢谢。