选择显示字体大小

使用properties类带来的好处

xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> 

许多开发者抱怨c++不能像java那样绑定properties类。java的properties类内在包含一个文件,该文件用来读写properties类中的属性,可以写成这样形式:<名字>=<数值>(例如:connecttointe.net=use ie)。

使用properties类的好处就是你可以很轻松的理解和修改它们。在本文的第一部分中,你将看到我们也可以在c++中使用properties类。本文的第二部分将向你演示通过使用操作符>>和<<把数据保存到properties类中是多么的容易。

现在介绍c++ properties文件的结构。该文件的每一行可以是下面三种情况中的某一种:

空行(认为它是注释中的一部分)

以‘#’ 开始的注释行

‘<名字>=<数值>’行,这是给一个属性赋值的语句

现在让我们再看看properties类的的特点:

注释是持久性的(当保存properties类时,它们不会丢失掉)。注意每一个注释都属于某个属性。在‘<名字>=<数值>’行上的注释行属于该‘<名字>’属性。

当保存properties类后,属性仍然保留自己的位置。

它对各种字符类型都有效:char、wchar_t等等

properties类的使用相当简单:

save():保存属性

has_property(strpropertyname):如果类中有该属性则返回‘真’

string get_property(strpropertyname):返回指定的属性(如果指定属性不存在,则抛出例外)

set_property(strpropertyname, strpropertyvalue):设置给定属性

stringget_property_comment( strpropertyname):返回属于指定属性的注释(如果指定属性的注释不存在,则抛出例外)

set_property_comment(strpropertyname, strpropertycomment):设置指定属性的注释(如果指定属性的注释不存在,则抛出例外)

下面是file_reader_writer类以及相应例子的代码。运行它之后,请查看properties.txt文件。看看访问和修改它是多么容易的一件事。

#include exception>

#include string>

#include sstream>

#include map>

#include vector>

#include fstream>

#include algorithm>

#include functional>

//允许字符串转化

template< class fromchartype, class tochartype>

inline std::basic_string< tochartype> convert_string( const std::basic_string< fromchartype> & strsource)

{

std::basic_string< tochartype> strdest;

int nsourcelen = strsource.length();

strdest.resize( nsourcelen);

for ( int idxchar = 0; idxchar < nsourcelen; idxchar++)

{ strdest[ idxchar] = ( tochartype)strsource[ idxchar]; }

return strdest;

}

// 用于trim_spaces;

template< class chartype>

struct is_char_in_str : public std::binary_function< chartype, std::basic_string< chartype>, bool>

{

bool operator()( chartype ch, const std::basic_string< chartype> & strsource) const

{ return (strsource.find( ch) != std::basic_string< chartype>::npos); }

};

//消除字符串中的空格

template< class chartype>

std::basic_string< chartype> trim_spaces( const std::basic_string< chartype> & strsource)

{

std::basic_string< chartype> strspaces; strspaces += ( chartype)&#39; &#39;; strspaces += ( chartype)&#39;\t&#39;;

typedef std::basic_string< chartype> string_type;

string_type::const_iterator

itfirst = std::find_if( strsource.begin(), strsource.end(),

std::not1( std::bind2nd( is_char_in_str< chartype>(), strspaces)));

string_type::const_reverse_iterator

ritlast = std::find_if( strsource.rbegin(), strsource.rend(),

std::not1( std::bind2nd( is_char_in_str< chartype>(), strspaces)));

string_type::const_iterator itlast = &*ritlast;

if ( itfirst <= itlast)

if ( itfirst != strsource.end())
return string_type( itfirst, itlast + 1);

return string_type();

}

// 当读写属性时的例外

class properties_exception : public std::exception

{

public:

properties_exception( const std::string & str) : m_strdescription( str) {}

const char * what() const { return m_strdescription.c_str(); }

private:

std::string m_strdescription;

};

// 从文件中读写属性

template< class chartype>

class file_reader_writer

{

typedef std::basic_string< chartype> string_type;

public:

// ... needed within the basic_properties!

typedef chartype char_type;

public:

file_reader_writer( const char * strfilename)

: m_bisdirty( false), m_strfilename( strfilename) { read_properties(); }

~file_reader_writer() { save(); }

void save()

{ write_properties(); }

bool has_property( const string_type & strpropertyname) const

{

propertiescollection::const_iterator itfound = m_collproperties.find( strpropertyname);

return ( itfound != m_collproperties.end());

}

const string_type & get_property( const string_type & strpropertyname) const

{

propertiescollection::const_iterator itfound = m_collproperties.find( strpropertyname);

if ( itfound != m_collproperties.end())

return itfound->second.m_strvalue;

else

throw properties_exception(

"cound not get property value for &#39;" + convert_string< char_type, char>( strpropertyname) +

"&#39;, since this property does not exist.");

}

void set_property( const string_type & strproperty, const string_type & strpropertyvalue)

{

propertiescollection::iterator itfound = m_collproperties.find( strproperty);

if ( itfound == m_collproperties.end())

// 它是一个新的属性

m_aproperties.push_back( strproperty);

m_collproperties[ strproperty].m_strvalue = strpropertyvalue;

m_bisdirty = true;

}

const string_type & get_property_comment( const string_type & strpropertyname) const

{

propertiescollection::const_iterator itfound = m_collproperties.find( strpropertyname);

if ( itfound != m_collproperties.end())

return itfound->second.m_strcomment;

else

throw properties_exception(

"cound not get property comment for &#39;" + convert_string< char_type, char>( strpropertyname) +

"&#39;, since this property does not exist.");

}

void set_property_comment( const string_type & strpropertyname, const string_type & strpropertycomment)

{

propertiescollection::iterator itfound = m_collproperties.find( strpropertyname);

if ( itfound != m_collproperties.end())

itfound->second.m_strcomment = strpropertycomment;

else

throw properties_exception(

"cound not set property comment for &#39;" + convert_string< char_type, char>( strpropertyname) +

"&#39;, since this property does not exist.");

m_bisdirty = true;

}

private:

static const char_type get_delimeter() { return &#39;=&#39;; }

static const char_type get_comment() { return &#39;#&#39;; }

void read_properties()

{

const char delimeter = get_delimeter();

const char comment = get_comment();

std::basic_ifstream< char_type> streamin( m_strfilename.c_str());

string_type strline;

string_type strcomment;

while ( std::getline( streamin, strline))

{

strline = trim_spaces( strline);
bool biscomment = strline.empty() ( strline[ 0] == comment);

if ( biscomment)

{ strcomment += strline; strcomment += &#39;\n&#39;; }

else

{

int idxdelimeter = strline.find( delimeter);

if ( idxdelimeter != string_type::npos)

{

string_type strpropertyname = strline.substr( 0, idxdelimeter);

string_type strpropertyvalue = strline.substr( idxdelimeter + 1);

strpropertyname = trim_spaces( strpropertyname);

strpropertyvalue = trim_spaces( strpropertyvalue);

m_collproperties.insert(

std::make_pair( strpropertyname, oneproperty( strpropertyvalue, strcomment)));

m_aproperties.push_back( strpropertyname);

strcomment.erase();

}

else

throw properties_exception(

"while reading from file &#39;" + m_strfilename +

"&#39;, we encountered an invalid line: \n" + convert_string< char_type, char>( strline));

}
}

m_strlastcomment = strcomment;

}

void write_properties() const

{

if ( !m_bisdirty)

// 无需保存

;return;

const char delimeter = get_delimeter();

std::basic_ofstream< char_type> streamout( m_strfilename.c_str());

propertiesarray::const_iterator

itfirst = m_aproperties.begin(), itlast = m_aproperties.end();

while ( itfirst != itlast)

{

const string_type & strpropertyname = *itfirst;

const oneproperty & property = m_collproperties.find( strpropertyname)->second;

write_property_comment( streamout, property.m_strcomment);

string_type strtowrite = strpropertyname;

strtowrite += &#39; &#39;; strtowrite += delimeter; strtowrite += &#39; &#39;;

streamout strtowrite << property.m_strvalue << std::endl;

++itfirst;

}

write_property_comment( streamout, m_strlastcomment);

m_bisdirty = false;

}

void write_property_comment( std::basic_ofstream< char_type> & streamout, const string_type & strcomment) const

{

const char comment = get_comment();

std::basic_stringstream< char_type> streamcomment( strcomment);

string_type strline;

while ( std::getline( streamcomment, strline))

{

if ( !strline.empty())

if ( strline[ 0] == comment)

streamout << strline << std::endl;

else

{

string_type strprefix;

strprefix += comment; strprefix += &#39; &#39;;

streamout << strprefix << strline << std::endl;

}

else

streamout << std::endl;

}
}

private:

// 我们用来读写的文件

std::string m_strfilename;

//如果自上次保存后属性又有修改则赋值为“真”

mutable bool m_bisdirty;

struct oneproperty

{

oneproperty() {}

oneproperty( const string_type & strvalue, const string_type & strcomment)

: m_strvalue( strvalue), m_strcomment( strcomment) {}

string_type m_strvalue;

string_type m_strcomment;

};

// 属性

typedef std::map< string_type, oneproperty> propertiescollection;

propertiescollection m_collproperties;

// ……确保我们是按同样的次序保存属性

// 读属性

typedef std::vector< string_type> propertiesarray;

propertiesarray m_aproperties;

// 读取所有属性后的注释

string_type m_strlastcomment;

};

下面是用到这个类的一个例子:

#include

int main(int argc, char* argv[])

{

file_reader_writer< char> rw( "properties.txt");

rw.set_property( "app path", "c:\program files\pfs\jokexplorer");

rw.set_property_comment( "app path", "where are we installed?");

rw.set_property( "version", "4.0.0.1");

rw.set_property_comment( "version", "what&#39;s our version?");

rw.set_property( "run on startup", "1");

rw.set_property_comment( "run on startup", "are we run, when the computer starts?");

rw.set_property( "automatic logoff minutes", "60");

rw.set_property_comment( "automatic logoff minutes", "when should we deconnect from the server?");

rw.set_property( "connect to inte.net", "use ie");

rw.set_property_comment( "connect to inte.net", "how are we to connect to the inte.net?");

std::cout << "this is how we connect to inte.net: " << rw.get_property( "connect to inte.net") << std::endl;

return 0;

}


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons