boost常用库案例
http://www.cnblogs.com/wangkangluo1/archive/2011/07/19/2110746.html1.boost::any
boost::any是一种通用的数据类型,可以将各种类型包装后统一放入容器内,最重要的它是类型安全的。有点象COM里面的variant。
使用方法:
any::type() 返回包装的类型
any_cast可用于any到其他类型的转化
#include <boost/any.hpp>
void test_any()
{
typedef std::vector<boost::any> many;
many a;
a.push_back(2);
a.push_back(string("test"));
for(unsigned int i=0;i<a.size();++i)
{
cout<<a[i].type().name()<<endl;
try
{
int result = any_cast<int>(a[i]);
cout<<result<<endl;
}
catch(boost::bad_any_cast & ex)
{
cout<<"cast error:"<<ex.what()<<endl;
}
}
}
2.boost::array
boost::array仅仅是对数组一层薄薄的封装,提供跟各种算法配合的iterator,使用方法很简单。注意:可以使用{}来初始化array,因为array所有的成员变量都是public的。
#include <boost/array.hpp> void test_array() { array<int,10> ai = {1,2,3}; for(size_t i=0;i<ai.size();++i) { cout<<ai[i]<<endl; } }
3.boost::lexical_cast
lexical_cast用于将字符串转换成各种数字类型(int,float,short etc.)。
#include <boost/lexical_cast.hpp> void test_lexical_cast() { int i = boost::lexical_cast<int>("123"); cout << i << endl; }
4.boost::format
boost::format是用于替代c里面的sprintf,优点是类型安全,不会因为类型和参数不匹配而导致程序崩溃了,而且还可以重复使用参数。
#include <boost/format.hpp> void test_format() { cout << boost::format("writing %1%, x=%2% : %3%-th try") % "toto" % 40.23 % 50 <<endl; format f("a=%1%,b=%2%,c=%3%,a=%1%"); f % "string" % 2 % 10.0; cout << f.str() << endl; }
5.boost::tokenizer
boost::tokenizer是用于切割字符串的,类似于Java里面的StringTokenizer。
#include <boost/tokenizer.hpp>
void test_tokenizer()
{
string s("This is , a ,test!");
boost::tokenizer<> tok(s);
for(tokenizer<>::iterator beg=tok.begin(); beg!=tok.end();++beg)
{
cout << *beg << " ";
}
}
6.boost::thread
boost::thread是为了提供跨平台的thread机制。利用boost::function来完成委托。
#include <boost/thread.hpp>
void mythread()
{
cout<<"hello,thread!"<<endl;
}
void test_thread()
{
boost::function< void () > f(mythread);
boost::thread t(f);
t.join();
cout<<"thread is over!"<<endl;
}
7.boost::serialization
boost::serialization提供object的序列化功能。而且提供好几种序列化的格式,比如text,binary,xml。
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
void test_serialization()
{
boost::archive::text_oarchive to(cout , boost::archive::no_header);
int i = 10;
string s = "This is a test ";
to & i;
to & s;
ofstream f("test.xml");
boost::archive::xml_oarchive xo(f);
xo & BOOST_SERIALIZATION_NVP(i) & BOOST_SERIALIZATION_NVP(s);
boost::archive::text_iarchive ti(cin , boost::archive::no_header);
ti & i & s;
cout <<"i="<< i << endl;
cout <<"s="<< s << endl;
}
8.boost::function
boost::function就是所谓的泛函数,能够对普通函数指针,成员函数指针,functor进行委托,达到迟调用的效果。
#include <boost/function.hpp>
int foo(int x,int y)
{
cout<< "(foo invoking)x = "<<x << " y = "<< y <<endl;
return x+y;
}
struct test
{
int foo(int x,int y)
{
cout<< "(test::foo invoking)x = "<<x << " y = "<< y <<endl;
return x+y;
}
};
void test_function()
{
boost::function<int (int,int)> f;
f = foo;
cout << "f(2,3)="<<f(2,3)<<endl;
test x;
/*f = std::bind1st(std::mem_fun(&test::foo), &x);*/
boost::function<int (test*,int,int)> f2;
f2 = &test::foo;
cout << "f2(5,3)="<<f2(&x,5,3)<<endl;
}
9.boost::shared_ptr
boost::shared_ptr就是智能指针的实现,不象std::auto_ptr,它是可以stl的容器一起使用的,非常的方便。
#include <boost/shared_ptr.hpp>
class Shared
{
public:
Shared()
{
cout << "ctor() called"<<endl;
}
Shared(const Shared & other)
{
cout << "copy ctor() called"<<endl;
}
~Shared()
{
cout << "dtor() called"<<endl;
}
Shared & operator = (const Shared & other)
{
cout << "operator = called"<<endl;
}
};
void test_shared_ptr()
{
typedef boost::shared_ptr<Shared> SharedSP;
typedef vector<SharedSP> VShared;
VShared v;
v.push_back(SharedSP(new Shared()));
v.push_back(SharedSP(new Shared()));
}
========
boost asio 简单示例
http://blog.chinaunix.net/uid-1720597-id-85507.html
客户端:
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
using boost::asio::ip::tcp;
using boost::asio::ip::address;
class session: public boost::enable_shared_from_this<session> {
public:
session(boost::asio::io_service &io_service, tcp::endpoint &endpoint)
: io_service_(io_service), socket_(io_service), endpoint_(endpoint)
{
}
void start() {
socket_.async_connect(endpoint_,
boost::bind(&session::handle_connect,
shared_from_this(),
boost::asio::placeholders::error));
}
private:
void handle_connect(const boost::system::error_code &error) {
if (error) {
if (error.value() != boost::system::errc::operation_canceled) {
std::cerr << boost::system::system_error(error).what() << std::endl;
}
socket_.close();
return;
}
static tcp::no_delay option(true);
socket_.set_option(option);
strcpy(buf, "Hello World!\n");
boost::asio::async_write(socket_,
boost::asio::buffer(buf, strlen(buf)),
boost::bind(&session::handle_write,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void handle_write(const boost::system::error_code& error, size_t bytes_transferred) {
memset(buf, sizeof(buf), 0);
boost::asio::async_read_until(socket_,
sbuf,
"\n",
boost::bind(&session::handle_read,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void handle_read(const boost::system::error_code& error, size_t bytes_transferred) {
std::cout << buf << std::endl;
}
private:
boost::asio::io_service &io_service_;
tcp::socket socket_;
tcp::endpoint &endpoint_;
char buf[1024];
boost::asio::streambuf sbuf;
};
typedef boost::shared_ptr<session> session_ptr;
int main(int argc, char* argv[])
{
boost::asio::io_service io_service;
tcp::endpoint endpoint(address::from_string("192.168.1.1"), 10028);
session_ptr new_session(new session(io_service, endpoint));
new_session->start();
io_service.run();
return 0;
}
服务器:
#include <string.h>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
using boost::asio::ip::tcp;
using boost::asio::ip::address;
class session: public boost::enable_shared_from_this<session> {
public:
session(boost::asio::io_service &io_service): socket_(io_service)
{
}
void start() {
static tcp::no_delay option(true);
socket_.set_option(option);
boost::asio::async_read_until(socket_,
sbuf_,
"\n",
boost::bind(&session::handle_read,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
tcp::socket &socket() {
return socket_;
}
private:
void handle_write(const boost::system::error_code& error, size_t bytes_transferred) {
boost::asio::async_read_until(socket_,
sbuf_,
"\n",
boost::bind(&session::handle_read,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void handle_read(const boost::system::error_code& error, size_t bytes_transferred) {
boost::asio::async_write(socket_,
sbuf_,
boost::bind(&session::handle_write,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
private:
tcp::socket socket_;
boost::asio::streambuf sbuf_;
};
typedef boost::shared_ptr<session> session_ptr;
class server {
public:
server(boost::asio::io_service &io_service, tcp::endpoint &endpoint)
: io_service_(io_service), acceptor_(io_service, endpoint)
{
session_ptr new_session(new session(io_service_));
acceptor_.async_accept(new_session->socket(),
boost::bind(&server::handle_accept,
this,
new_session,
boost::asio::placeholders::error));
}
void handle_accept(session_ptr new_session, const boost::system::error_code& error) {
if (error) {
return;
}
new_session->start();
new_session.reset(new session(io_service_));
acceptor_.async_accept(new_session->socket(),
boost::bind(&server::handle_accept,
this,
new_session,
boost::asio::placeholders::error));
}
void run() {
io_service_.run();
}
private:
boost::asio::io_service &io_service_;
tcp::acceptor acceptor_;
};
int main(int argc, char* argv[])
{
boost::asio::io_service io_service;
tcp::endpoint endpoint(address::from_string("192.168.1.1"), 10028);
server s(io_service, endpoint);
s.run();
return 0;
}
编译:
g++ -Wall -o client client.cpp -lboost_system
g++ -Wall -o server server.cpp -lboost_system
这里需要注意的是: async_write, async_read, async_read_until 都是需要达到特定条件才会调用回调函数,
在调用回调函数之前, 不能再次调用, 否则接收到的数据很可能是乱的. 所以, 在实际代码当中, 会有一个写缓冲队列, 当需要write的时, 先放到队列中, 如果队列个数为1, 则调用async_write, 否则等待函数回调, 当函数回调时将首个元素从队列中移除, 然后接着发送下一个, 直到队列为空.
对于client, 由于is_open在async_connect之后就是true状态了, 因此在async_connect回调返回之前没有方法知道是否已经连接成功, 实际代码当中一般会增加一个变量以表示该套接字是否已经允许发送数据.
========
C++之BOOST字符串查找示例
http://www.jb51.net/article/56642.htm
这篇文章主要介绍了C++之BOOST字符串查找的方法,实例演示了boost针对字符串的查找、判定及替换等操作,
本文实例讲述了C++中BOOST字符串查找的方法,分享给大家供大家参考。具体方法如下:
BOOST 字符串查找示例
复制代码 代码如下:
#include <string>
#include <iostream>
#include <algorithm>
#include <functional>
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string/find.hpp>
using namespace std;
using namespace boost;
int main()
{
cout << "* Find Example *" << endl << endl;
string str1("abc___cde___efg");
string str2("abc");
// find "cde" substring
iterator_range<string::iterator> range=find_first( str1, string("cde") );
// convert a substring to upper case
// note that iterator range can be directly passed to the algorithm
to_upper( range );
cout << "str1 with upper-cased part matching cde: " << str1 << endl;
// get a head of the string
iterator_range<string::iterator> head=find_head( str1, 3 );
cout << "head(3) of the str1: " << string( head.begin(), head.end() ) << endl;
// get the tail
head=find_tail( str2, 5 );
cout << "tail(5) of the str2: " << string( head.begin(), head.end() ) << endl;
// char processing
char text[]="hello dolly!";
iterator_range<char*> crange=find_last(text,"ll");
// transform the range ( add 1 )
transform( crange.begin(), crange.end(), crange.begin(), bind2nd( plus<char>(), 1 ) );
// uppercase the range
to_upper( crange );
cout << text << endl;
cout << endl;
return 0;
}
boost 判定函数的使用
复制代码 代码如下:
#include <string>
#include <iostream>
#include <functional>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/bind.hpp>
using namespace std;
using namespace boost;
int main()
{
cout << "* Predicate Example *" << endl << endl;
string str1("123xxx321");
string str2("abc");
// Check if str1 starts with '123'
cout << "str1 starts with \"123\": " <<
(starts_with( str1, string("123") )?"true":"false") << endl;
// Check if str1 ends with '123'
cout << "str1 ends with \"123\": " <<
(ends_with( str1, string("123") )?"true":"false") << endl;
// Check if str1 containes 'xxx'
cout << "str1 contains \"xxx\": " <<
(contains( str1, string("xxx") )?"true":"false") << endl;
// Check if str2 equals to 'abc'
cout << "str2 equals \"abc\": " <<
(equals( str2, string("abc") )?"true":"false") << endl;
// Classification functors and all predicate
if ( all(";.,", is_punct() ) )
{
cout << "\";.,\" are all punctuation characters" << endl;
}
// Classification predicates can be combined
if ( all("abcxxx", is_any_of("xabc") && !is_space() ) )
{
cout << "true" << endl;
}
cout << endl;
return 0;
}
boost替换示例
复制代码 代码如下:
#include <string>
#include <iostream>
#include <iterator>
//#include <boost/algorithm/string/replace.hpp>
//#include <boost/algorithm/string/erase.hpp>
//#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string.hpp>
//Following two includes contain second-layer function.
//They are already included by first-layer header
//#include <boost/algorithm/string/replace2.hpp>
//#include <boost/algorithm/string/find2.hpp>
using namespace std;
using namespace boost;
// uppercase formatter
/*
Convert an input to upper case.
Note, that this formatter can be used only on std::string inputs.
*/
inline string upcase_formatter(
const iterator_range<string::const_iterator>& Replace )
{
string Temp(Replace.begin(), Replace.end());
to_upper(Temp);
return Temp;
}
int main()
{
cout << "* Replace Example *" << endl << endl;
string str1("abc___cde___efg");
// Erase 6-9th characters from the string
cout << "str1 without 6th to 9th character:" <<
erase_range_copy( str1, make_iterator_range(str1.begin()+6, str1.begin()+9) ) << endl;
// Replace 6-9th character with '+++'
cout << "str1 with 6th to 9th character replaced with '+++': " <<
replace_range_copy(
str1, make_iterator_range(str1.begin()+6, str1.begin()+9), "+++" ) << endl;
cout << "str1 with 'cde' replaced with 'XYZ': ";
// Replace first 'cde' with 'XYZ'. Modify the input
replace_first_copy( ostream_iterator<char>(cout), str1, "cde", "XYZ" );
cout << endl;
// Replace all '___'
cout << "str1 with all '___' replaced with '---': " <<
replace_all_copy( str1, "___", "---" ) << endl;
// Erase all '___'
cout << "str1 without all '___': " <<
erase_all_copy( str1, "___" ) << endl;
// replace third and 5th occurrence of _ in str1
// note that nth argument is 0-based
replace_nth( str1, "_", 4, "+" );
replace_nth( str1, "_", 2, "+" );
cout << "str1 with third and 5th occurrence of _ replace: " << str1 << endl;
// Custom formatter examples
string str2("abC-xxxx-AbC-xxxx-abc");
// Find string 'abc' ignoring the case and convert it to upper case
cout << "Upcase all 'abc'(s) in the str2: " <<
find_format_all_copy(
str2,
first_finder("abc", is_iequal()),
upcase_formatter );
cout << endl;
return 0;
}
========
boost流的小例子
http://blog.sina.com.cn/s/blog_62b4e3ff0101amtv.html
标准流只能处理:标准输入输出(stdin,stdout,stderr),文件,字符串。
现在想用流的思想处理一个内存块。将一个内存块当做一个“设备”
//
//利用标准库的stringstream处理
void Chapter1()
{
char data[100];
strcpy(data,"123 456 789"); //要处理的数组,当做一个内存块
//我们不关心内存是从哪里来的,数据如何赋值上去的。
std::string str(data); //一次拷贝
std::stringstream ss(str);//二次拷贝
//缺点:1)数据多次拷贝。2)只能处理char(0)结束的“字符串”,不能处理更广泛的“字符流”。
int x,y,z;
ss >> x >> y >> z ;
return 0;
}
/利用“小作坊”生产的“家酿”代码
#include <streambuf>
#include <istream>
struct my_streambuf : public std::basic_streambuf
{
my_streambuf(char* buffer, std::streamsize length)
{
setg(buffer, buffer, buffer + length);
setp(buffer, buffer + length);
}
};
void Chapter2()
{
char data[100];
strcpy(data,"123 456 789");
my_streambuf buff(data,100); //流缓冲,负责对设备操作
std::istream iss(&buff); //标准流,负责对用户数据的格式化,非格式化处理。
int x,y,z;
iss >> x >> y >> z ;
return 0;
}
//
//利用boost.iostreams库处理
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>
#include <iomanip>
void Chapter3()
{
namespace io = boost::iostreams;
char buff[32]={0};
io::array one(buff,32);
//io::array 的身世
//别名 boost::iostreams::basic_array<char>
//符合 概念<SeekableDevice> 精化于 {概念<Source>,概念<Sink>} 意味着:字符序列的来源,去向。
//具有 模式<Seekable> 意味着:可以随意移动读写头
//符合 概念<Direct> 意味着:不用文件缓存的那种机制。经过另一个buffer的缓冲是毫无必要的。
io::stream<io::array> s(one);
s << "hello" << ' ' << "world " << std::setw(4) << std::setfill('0') << 123 ; //输出
io::seek(s,0,std::ios_base::beg); //移动读写头的位置
std::string s1,s2,s3;
s >> s1 >> s2 >> s3; //输入
s.clear(); //复位标志位为ios_base::good。因为前面的操作遇到字符char(0),将流状态变成eof
io::seek(s,0,std::ios_base::beg);
char i;
for (i='a';s; ++i) //循环的写任意多个字符,很快的就能遇到失败。
//失败的原因是:数组不是文件,只能写数组定义时的最大值。
{ //即使是文件能自动增长,也有物理的最大限制。
s << i ;
if (!s) break;
}
char* pstr = "HELLO WORLD" ;
io::array another(pstr,strlen(pstr)); //定义另一个“数组”,作为一个新设备(Device)。
s.close(); //关闭旧Device
if (!s.is_open()){
s.open(another); //打开另一个Device
}
s >> s1 >> s2; //输入
//s << 123 //不要尝试它,pstr指向一个被写保护的内存区,任何写尝试都会让程序挂掉。
}
========
boost::filesystem遍历目录
http://blog.csdn.net/hhhbbb/article/details/6799564
#include <boost::filesystem.hpp>
using namespace boost::filesystem;
void file_executor::iterate_folder(const string full_path)
{
directory_iterator end;
for(directory_iterator pos(full_path);pos !=end; ++pos){
boost::filesystem::path path_(*pos);
if(is_regular(path_)){
string s= path_.string();
vector_files.push_back(s);
files_num ++;
}
else if(is_directory(path_)){
iterate_folder(path_.string());
}
}
}
========