之前作java項目的時候,須要一些配置參數,java提供了Properties 類 來操做,存儲配置,挺方便的,如今既然在看c++,就想着用c++來實現這麼一個類。java
要求:ios
1.支持註釋,單行,多行註釋都行c++
2.簡單的key/value 模型安全
3.獲取,修改,清空,存儲操做等學習
接口頭文件:properties.h測試
#ifndef PROPERTIES_H #define PROPERTIES_H #include <string> #include <map> namespace huals{ class Properties{ private //配置文件路徑 std::string filepath; //配置選項存儲pair<key,value> std::map<std::string,std::string> pps; //註釋存儲pair<key,annotation> std::map<std::string,std::string> ann; public: Properties(std::string file); std::string Get_property(std::string key); void Set_property(std::string key,std::string value); int Save(); void Clear(); //測試用,輸出配置文件的內容 void Print(); }; } #include "properties.cpp" #endif
具體實現:properties.cpp編碼
#include <iostream> #include <fstream> #include <string> #include <map> #include <sstream> #include <cstring> namespace huals{ //may throw error Properties::Properties(std::string file):filepath(file){ std::fstream in; in.open(file.c_str()); if(!in) return ; std::string line; //註釋 std::string annotation; while(getline(in,line)){ std::string key; std::string value; /* *去掉字符串頭尾空字符 */ int start,end; start=line.find_first_not_of(" "); end=line.find_last_not_of(" "); if(start<0) start=0; line=line.substr(start,end-start+1); //若是以#開頭,則爲配置文件 if('#'==line[0]){ annotation+=line+"\n"; }else{ start=line.find_first_of("="); key=line.substr(0,start); value=line.substr(start+1,line.size()-start); pps.insert(make_pair(key,value)); /* *註釋是在配置的前面,若是註釋不爲空,則插入註釋map */ if(!annotation.empty()){ ann.insert(make_pair(key,annotation)); annotation.clear(); } } } in.close(); } //if the key not in map, return empty string std::string Properties::Get_property(std::string key){ std::string value; std::map<std::string,std::string>::iterator it=pps.find(key); if(it!=pps.end()) value=it->second; return value; } /* *設置配置項,key不存在,將會添加 */ void Properties::Set_property(std::string key,std::string value){ pps[key]=value; } /* *存檔,寫入配置文件 */ int Properties::Save(){ std::ofstream out; out.open(filepath.c_str(),std::ofstream::out); std::map<std::string,std::string>::iterator temp,it=pps.begin(); while(it!=pps.end()){ std::string line; temp=ann.find(it->first); if(temp!=ann.end()) out<<temp->second; line+=it->first+"="; line+=it->second; out<<line<<std::endl; it++; } out.close(); return 0; } /* *清空配置項,注意清空後調用Save()纔有效 */ void Properties::Clear(){ pps.clear(); ann.clear(); } //配置文件輸出測試 void Properties::Print(){ std::map<std::string,std::string>::iterator temp,it=pps.begin(); while(it!=pps.end()){ std::string line; temp=ann.find(it->first); if(temp!=ann.end()) std::cout<<temp->second; line+=it->first+"="; line+=it->second; std::cout<<line<<std::endl; it++; } } }
通過測試,這個類基本知足要求。spa
待改進:線程
1.中文支持,沒有特別設置編碼這些信息,樓主在fedora 系統編碼utf-8下測試是支持中文的code
2.異常處理,讀寫配置文件均可能發生異常,這個須要改進
3.線程安全,若是有多個線程同時讀寫配置文件,需重寫此類
下面順便寫一個簡單c++ 整數轉成字符串東東,不用itoa這種偏c的東西
#include <iostream> #include <sstream> #include <string> int main(void){ ostringstream oss; int a=12; oss<<a; std::string str=oss.str(); std::cout<<str<<std::endl; return 0; }
over,好好學習,daydayup!