|
[工作日志]ini file class |
// IniFile.cpp: Implementation of the CIniFile class.// Written by: Adam Clauss// Email: cabadam@tamu.edu// You may use this class/code as you wish in your programs. Feel free to distribute it, and// email suggested changes to me.//// Rewritten by: Shane Hill// Date: 21/08/2001// Email: Shane.Hill@dsto.defence.gov.au// Reason: Remove dependancy on MFC. Code should compile on any// platform. Tested on Windows/Linux/Irix//////////////////////////////////////////////////////////////////////
#ifndef CIniFile_H#define CIniFile_H
// C++ Includes#include <string>#include <vector>
// C Includes#include <stdlib.h>
#define MAX_KEYNAME 128#define MAX_VALUENAME 128#define MAX_VALUEDATA 2048
class CIniFile {private: bool caseInsensitive; string path; struct key { vector<string> names; vector<string> values; vector<string> comments; }; vector<key> keys; vector<string> names; vector<string> comments; string CheckCase( string s) const;
public: enum errors{ noID = -1}; CIniFile( string const iniPath = ""); virtual ~CIniFile() {}
// Sets whether or not keynames and valuenames should be case sensitive. // The default is case insensitive.vfg void CaseSensitive() {caseInsensitive = false;} void CaseInsensitive() {caseInsensitive = true;}
// Sets path of ini file to read and write from. void Path(string const newPath) {path = newPath;} string Path() const {return path;} void SetPath(string const newPath) {Path( newPath);}
// Reads ini file specified using path. // Returns true if successful, false otherwise. bool ReadFile(); // Writes data stored in class to ini file. bool WriteFile(); // Deletes all stored ini data. void Erase(); void Clear() {Erase();} void Reset() {Erase();}
// Returns index of specified key, or noID if not found. long FindKey( string const keyname) const;
// Returns index of specified value, in the specified key, or noID if not found. long FindValue( unsigned const keyID, string const valuename) const;
// Returns number of keys currently in the ini. unsigned NumKeys() const {return names.size();} unsigned GetNumKeys() const {return NumKeys();}
// Add a key name. unsigned AddKeyName( string const keyname);
// Returns key names by index. string KeyName( unsigned const keyID) const; string GetKeyName( unsigned const keyID) const {return KeyName(keyID);}
// Returns number of values stored for specified key. unsigned NumValues( unsigned const keyID); unsigned GetNumValues( unsigned const keyID) {return NumValues( keyID);} unsigned NumValues( string const keyname); unsigned GetNumValues( string const keyname) {return NumValues( keyname);}
// Returns value name by index for a given keyname or keyID. string ValueName( unsigned const keyID, unsigned const valueID) const; string GetValueName( unsigned const keyID, unsigned const valueID) const { return ValueName( keyID, valueID); } string ValueName( string const keyname, unsigned const valueID) const; string GetValueName( string const keyname, unsigned const valueID) const { return ValueName( keyname, valueID); }
// Gets value of [keyname] valuename =. // Overloaded to return string, int, and double. // Returns defValue if key/value not found. string GetValue( unsigned const keyID, unsigned const valueID, string const defValue = "") const; string GetValue(string const keyname, string const valuename, string const defValue = "") const; int GetValueI(string const keyname, string const valuename, int const defValue = 0) const; bool GetValueB(string const keyname, string const valuename, bool const defValue = false) const { return bool( GetValueI( keyname, valuename, int( defValue))); } double GetValueF(string const keyname, string const valuename, double const defValue = 0.0) const; // This is a variable length formatted GetValue routine. All these voids // are required because there is no vsscanf() like there is a vsprintf(). // Only a maximum of 8 variable can be read. unsigned GetValueV( string const keyname, string const valuename, char *format, void *v1 = 0, void *v2 = 0, void *v3 = 0, void *v4 = 0, void *v5 = 0, void *v6 = 0, void *v7 = 0, void *v8 = 0, void *v9 = 0, void *v10 = 0, void *v11 = 0, void *v12 = 0, void *v13 = 0, void *v14 = 0, void *v15 = 0, void *v16 = 0);
// Sets value of [keyname] valuename =. // Specify the optional paramter as false (0) if you do not want it to create // the key if it doesn't exist. Returns true if data entered, false otherwise. // Overloaded to accept string, int, and double. bool SetValue( unsigned const keyID, unsigned const valueID, string const value); bool SetValue( string const keyname, string const valuename, string const value, bool const create = true); bool SetValueI( string const keyname, string const valuename, int const value, bool const create = true); bool SetValueB( string const keyname, string const valuename, bool const value, bool const create = true) { return SetValueI( keyname, valuename, int(value), create); } bool SetValueF( string const keyname, string const valuename, double const value, bool const create = true); bool SetValueV( string const keyname, string const valuename, char *format, ...);
// Deletes specified value. // Returns true if value existed and deleted, false otherwise. bool DeleteValue( string const keyname, string const valuename); // Deletes specified key and all values contained within. // Returns true if key existed and deleted, false otherwise. bool DeleteKey(string keyname);
// Header comment functions. // Header comments are those comments before the first key. // // Number of header comments. unsigned NumHeaderComments() {return comments.size();} // Add a header comment. void HeaderComment( string const comment); // Return a header comment. string HeaderComment( unsigned const commentID) const; // Delete a header comment. bool DeleteHeaderComment( unsigned commentID); // Delete all header comments. void DeleteHeaderComments() {comments.clear();}
// Key comment functions. // Key comments are those comments within a key. Any comments // defined within value names will be added to this list. Therefore, // these comments will be moved to the top of the key definition when // the CIniFile::WriteFile() is called. // // Number of key comments. unsigned NumKeyComments( unsigned const keyID) const; unsigned NumKeyComments( string const keyname) const; // Add a key comment. bool KeyComment( unsigned const keyID, string const comment); bool KeyComment( string const keyname, string const comment); // Return a key comment. string KeyComment( unsigned const keyID, unsigned const commentID) const; string KeyComment( string const keyname, unsigned const commentID) const; // Delete a key comment. bool DeleteKeyComment( unsigned const keyID, unsigned const commentID); bool DeleteKeyComment( string const keyname, unsigned const commentID); // Delete all comments for a key. bool DeleteKeyComments( unsigned const keyID); bool DeleteKeyComments( string const keyname);};
#endif
// IniFile.cpp: Implementation of the CIniFile class.// Written by: Adam Clauss// Email: cabadam@houston.rr.com// You may use this class/code as you wish in your programs. Feel free to distribute it, and// email suggested changes to me.//// Rewritten by: Shane Hill// Date: 21/08/2001// Email: Shane.Hill@dsto.defence.gov.au// Reason: Remove dependancy on MFC. Code should compile on any// platform.//////////////////////////////////////////////////////////////////////
// C++ Includes#include <iostream>#include <fstream>#include <strstream>
using namespace std;
// C Includes#include <stdio.h>#include <stdarg.h>#include <ctype.h>
// Local Includes#include "iniFile.h"
#if defined(WIN32)#define iniEOL endl#else#define iniEOL '\r' << endl#endif
CIniFile::CIniFile( string const iniPath){ Path( iniPath); caseInsensitive = true;}
bool CIniFile::ReadFile(){ // Normally you would use ifstream, but the SGI CC compiler has // a few bugs with ifstream. So ... fstream used. fstream f; string line; string keyname, valuename, value; string::size_type pLeft, pRight;
f.open( path.c_str(), ios::in); if ( f.fail()) return false; while( getline( f, line)) { // To be compatible with Win32, check for existence of '\r'. // Win32 files have the '\r' and Unix files don't at the end of a line. // Note that the '\r' will be written to INI files from // Unix so that the created INI file can be read under Win32 // without change. if ( line[line.length() - 1] == '\r') line = line.substr( 0, line.length() - 1); if ( line.length()) { // Check that the user hasn't openned a binary file by checking the first // character of each line! if ( !isprint( line[0])) { printf( "Failing on char %d\n", line[0]); f.close(); return false; } if (( pLeft = line.find_first_of(";#[=")) != string::npos) { switch ( line[pLeft]) { case '[': if ((pRight = line.find_last_of("]")) != string::npos && pRight > pLeft) { keyname = line.substr( pLeft + 1, pRight - pLeft - 1); AddKeyName( keyname); } break; case '=': valuename = line.substr( 0, pLeft); value = line.substr( pLeft + 1); SetValue( keyname, valuename, value); break; case ';': case '#': if ( !names.size()) HeaderComment( line.substr( pLeft + 1)); else KeyComment( keyname, line.substr( pLeft + 1)); break; } } } }
f.close(); if ( names.size()) return true; return false;}
bool CIniFile::WriteFile(){ unsigned commentID, keyID, valueID; // Normally you would use ofstream, but the SGI CC compiler has // a few bugs with ofstream. So ... fstream used. fstream f;
f.open( path.c_str(), ios::out); if ( f.fail()) return false;
// Write header comments. for ( commentID = 0; commentID < comments.size(); ++commentID) f << ';' << comments[commentID] << iniEOL; if ( comments.size()) f << iniEOL;
// Write keys and values. for ( keyID = 0; keyID < keys.size(); ++keyID) { f << '[' << names[keyID] << ']' << iniEOL; // Comments. for ( commentID = 0; commentID < keys[keyID].comments.size(); ++commentID) f << ';' << keys[keyID].comments[commentID] << iniEOL; // Values. for ( valueID = 0; valueID < keys[keyID].names.size(); ++valueID) f << keys[keyID].names[valueID] << '=' << keys[keyID].values[valueID] << iniEOL; f << iniEOL; } f.close(); return true;}
long CIniFile::FindKey( string const keyname) const{ for ( unsigned keyID = 0; keyID < names.size(); ++keyID) if ( CheckCase( names[keyID]) == CheckCase( keyname)) return long(keyID); return noID;}
long CIniFile::FindValue( unsigned const keyID, string const valuename) const{ if ( !keys.size() || keyID >= keys.size()) return noID;
for ( unsigned valueID = 0; valueID < keys[keyID].names.size(); ++valueID) if ( CheckCase( keys[keyID].names[valueID]) == CheckCase( valuename)) return long(valueID); return noID;}
unsigned CIniFile::AddKeyName( string const keyname){ names.resize( names.size() + 1, keyname); keys.resize( keys.size() + 1); return names.size() - 1;}
string CIniFile::KeyName( unsigned const keyID) const{ if ( keyID < names.size()) return names[keyID]; else return "";}
unsigned CIniFile::NumValues( unsigned const keyID){ if ( keyID < keys.size()) return keys[keyID].names.size(); return 0;}
unsigned CIniFile::NumValues( string const keyname){ long keyID = FindKey( keyname); if ( keyID == noID) return 0; return keys[keyID].names.size();}
string CIniFile::ValueName( unsigned const keyID, unsigned const valueID) const{ if ( keyID < keys.size() && valueID < keys[keyID].names.size()) return keys[keyID].names[valueID]; return "";}
string CIniFile::ValueName( string const keyname, unsigned const valueID) const{ long keyID = FindKey( keyname); if ( keyID == noID) return ""; return ValueName( keyID, valueID);}
bool CIniFile::SetValue( unsigned const keyID, unsigned const valueID, string const value){ if ( keyID < keys.size() && valueID < keys[keyID].names.size()) keys[keyID].values[valueID] = value;
return false;}
bool CIniFile::SetValue( string const keyname, string const valuename, string const value, bool const create){ long keyID = FindKey( keyname); if ( keyID == noID) { if ( create) keyID = long( AddKeyName( keyname)); else return false; }
long valueID = FindValue( unsigned(keyID), valuename); if ( valueID == noID) { if ( !create) return false; keys[keyID].names.resize( keys[keyID].names.size() + 1, valuename); keys[keyID].values.resize( keys[keyID].values.size() + 1, value); } else keys[keyID].values[valueID] = value;
return true;}
bool CIniFile::SetValueI( string const keyname, string const valuename, int const value, bool const create){ char svalue[MAX_VALUEDATA];
sprintf( svalue, "%d", value); return SetValue( keyname, valuename, svalue);}
bool CIniFile::SetValueF( string const keyname, string const valuename, double const value, bool const create){ char svalue[MAX_VALUEDATA];
sprintf( svalue, "%f", value); return SetValue( keyname, valuename, svalue);}
bool CIniFile::SetValueV( string const keyname, string const valuename, char *format, ...){ va_list args; char value[MAX_VALUEDATA];
va_start( args, format); vsprintf( value, format, args); va_end( args); return SetValue( keyname, valuename, value);}
string CIniFile::GetValue( unsigned const keyID, unsigned const valueID, string const defValue) const{ if ( keyID < keys.size() && valueID < keys[keyID].names.size()) return keys[keyID].values[valueID]; return defValue;}
string CIniFile::GetValue( string const keyname, string const valuename, string const defValue) const{ long keyID = FindKey( keyname); if ( keyID == noID) return defValue;
long valueID = FindValue( unsigned(keyID), valuename); if ( valueID == noID) return defValue;
return keys[keyID].values[valueID];}
int CIniFile::GetValueI(string const keyname, string const valuename, int const defValue) const{ char svalue[MAX_VALUEDATA];
sprintf( svalue, "%d", defValue); return atoi( GetValue( keyname, valuename, svalue).c_str()); }
double CIniFile::GetValueF(string const keyname, string const valuename, double const defValue) const{ char svalue[MAX_VALUEDATA];
sprintf( svalue, "%f", defValue); return atof( GetValue( keyname, valuename, svalue).c_str()); }
// 16 variables may be a bit of over kill, but hey, it's only code.unsigned CIniFile::GetValueV( string const keyname, string const valuename, char *format, void *v1, void *v2, void *v3, void *v4, void *v5, void *v6, void *v7, void *v8, void *v9, void *v10, void *v11, void *v12, void *v13, void *v14, void *v15, void *v16){ string value; // va_list args; unsigned nVals;
value = GetValue( keyname, valuename); if ( !value.length()) return false; // Why is there not vsscanf() function. Linux man pages say that there is // but no compiler I've seen has it defined. Bummer! // // va_start( args, format); // nVals = vsscanf( value.c_str(), format, args); // va_end( args);
nVals = sscanf( value.c_str(), format, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
return nVals;}
bool CIniFile::DeleteValue( string const keyname, string const valuename){ long keyID = FindKey( keyname); if ( keyID == noID) return false;
long valueID = FindValue( unsigned(keyID), valuename); if ( valueID == noID) return false;
// This looks strange, but is neccessary. vector<string>::iterator npos = keys[keyID].names.begin() + valueID; vector<string>::iterator vpos = keys[keyID].values.begin() + valueID; keys[keyID].names.erase( npos, npos + 1); keys[keyID].values.erase( vpos, vpos + 1);
return true;}
bool CIniFile::DeleteKey( string const keyname){ long keyID = FindKey( keyname); if ( keyID == noID) return false;
// Now hopefully this destroys the vector lists within keys. // Looking at <vector> source, this should be the case using the destructor. // If not, I may have to do it explicitly. Memory leak check should tell. // memleak_test.cpp shows that the following not required. //keys[keyID].names.clear(); //keys[keyID].values.clear();
vector<string>::iterator npos = names.begin() + keyID; vector<key>::iterator kpos = keys.begin() + keyID; names.erase( npos, npos + 1); keys.erase( kpos, kpos + 1);
return true;}
void CIniFile::Erase(){ // This loop not needed. The vector<> destructor seems to do // all the work itself. memleak_test.cpp shows this. //for ( unsigned i = 0; i < keys.size(); ++i) { // keys[i].names.clear(); // keys[i].values.clear(); //} names.clear(); keys.clear(); comments.clear();}
void CIniFile::HeaderComment( string const comment){ comments.resize( comments.size() + 1, comment);}
string CIniFile::HeaderComment( unsigned const commentID) const{ if ( commentID < comments.size()) return comments[commentID]; return "";}
bool CIniFile::DeleteHeaderComment( unsigned commentID){ if ( commentID < comments.size()) { vector<string>::iterator cpos = comments.begin() + commentID; comments.erase( cpos, cpos + 1); return true; } return false;}
unsigned CIniFile::NumKeyComments( unsigned const keyID) const{ if ( keyID < keys.size()) return keys[keyID].comments.size(); return 0;}
unsigned CIniFile::NumKeyComments( string const keyname) const{ long keyID = FindKey( keyname); if ( keyID == noID) return 0; return keys[keyID].comments.size();}
bool CIniFile::KeyComment( unsigned const keyID, string const comment){ if ( keyID < keys.size()) { keys[keyID].comments.resize( keys[keyID].comments.size() + 1, comment); return true; } return false;}
bool CIniFile::KeyComment( string const keyname, string const comment){ long keyID = FindKey( keyname); if ( keyID == noID) return false; return KeyComment( unsigned(keyID), comment);}
string CIniFile::KeyComment( unsigned const keyID, unsigned const commentID) const{ if ( keyID < keys.size() && commentID < keys[keyID].comments.size()) return keys[keyID].comments[commentID]; return "";}
string CIniFile::KeyComment( string const keyname, unsigned const commentID) const{ long keyID = FindKey( keyname); if ( keyID == noID) return ""; return KeyComment( unsigned(keyID), commentID);}
bool CIniFile::DeleteKeyComment( unsigned const keyID, unsigned const commentID){ if ( keyID < keys.size() && commentID < keys[keyID].comments.size()) { vector<string>::iterator cpos = keys[keyID].comments.begin() + commentID; keys[keyID].comments.erase( cpos, cpos + 1); return true; } return false;}
bool CIniFile::DeleteKeyComment( string const keyname, unsigned const commentID){ long keyID = FindKey( keyname); if ( keyID == noID) return false; return DeleteKeyComment( unsigned(keyID), commentID);}
bool CIniFile::DeleteKeyComments( unsigned const keyID){ if ( keyID < keys.size()) { keys[keyID].comments.clear(); return true; } return false;}
bool CIniFile::DeleteKeyComments( string const keyname){ long keyID = FindKey( keyname); if ( keyID == noID) return false; return DeleteKeyComments( unsigned(keyID));}
string CIniFile::CheckCase( string s) const{ if ( caseInsensitive) for ( string::size_type i = 0; i < s.length(); ++i) s[i] = tolower(s[i]); return s;}
//info.h 为自己的应用提供接口#include <string>
using namespace std;class CGetInfo{public: CGetInfo(); CGetInfo(string iniFileAddress); ~CGetInfo() {} string GetEmail(); int GetRtime(); int GetRnumber(); string GetLlist(); string GetRlist(); string GetIp(); int GetPort(); string GetFilename(); string GetUsername(); string GetPassword();private: string m_iniFileAddress;};
//info.cpp
#include <stdio.h>#include <string.h>#include "info.h"#include "iniFile.h"
CIniFile iniFile;
CGetInfo::CGetInfo(){ iniFile.Path("./ini_test.ini"); iniFile.ReadFile();}CGetInfo::CGetInfo(string iniFileAddress){ m_iniFileAddress=iniFileAddress; iniFile.Path(m_iniFileAddress); iniFile.ReadFile();} string CGetInfo::GetEmail(){ return iniFile.GetValue( "userinfo", "emailadd");} string CGetInfo::GetFilename(){ return iniFile.GetValue( "fileinfo", "filename");} string CGetInfo::GetIp(){ return iniFile.GetValue( "hostinfo", "ipaddress");} string CGetInfo::GetLlist(){ return iniFile.GetValue( "fileinfo", "locallist");} string CGetInfo::GetPassword(){ return iniFile.GetValue( "userinfo", "password");}int CGetInfo::GetPort(){ return iniFile.GetValueI( "hostinfo", "port");}string CGetInfo::GetRlist(){ return iniFile.GetValue( "fileinfo", "remotelist");}int CGetInfo::GetRnumber(){ return iniFile.GetValueI( "timeinfo", "retrynumber");}int CGetInfo::GetRtime(){ return iniFile.GetValueI( "timeinfo", "retrytime");} string CGetInfo::GetUsername(){ return iniFile.GetValue( "userinfo", "username");}
//test#include <iostream>
using namespace std;#include <string>#include "iniFile.h"#include "info.h"
int main(){ //CGetInfo getInfo("c:\\ini_test.ini"); CGetInfo getInfo; string sl;
sl=getInfo.GetEmail(); cout<< sl<<endl;
int i; cin>>i; return 0;}
ini_test.ini 文件放在自己设定的路径下,或者放在默认路径当前路径下[hostinfo]ipaddress=127.0.0.1port=21; This is another test comment for 386enh; This is another test comment for 386enh
[fileinfo]filename=mappoint.hlocallist=f:\download\mappoint.hremotelist=c:\mappoint.h
[timeinfo]retrynumber=5retrytime=2
[userinfo]username=casperpassword=123456emailadd=huimingsu@nettech-global.com
500)this.width=500'>ini.rar
|
|
|
|

|
.: 公告
|
|
| « | Mar.2026 | » | | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | | | | |
|
.: 我的分类(专题)
|
|

.: 最新日志
.: 最新回复
|
|

blog名称:Natural Pink 日志总数:49 评论数量:12 留言数量:0 访问次数:121206 建立时间:2006年7月25日 |
|

.: 留言板
|

.: 链接
|

|