C++ boost 实例学习

boost生成和解析json的完整例子

http://blog.csdn.net/dotphoenix/article/details/27081377

//  
//  json_parser.h  
//  mongoose  
//  
//  Created by Alex on 5/26/14.  
//  Copyright (c) 2014 Cenbong. All rights reserved.  
//  
  
#ifndef __mongoose__json_parser__  
#define __mongoose__json_parser__  
#include   
#include   
#include   
class sms_info  
{  
    sms_info()  
    {  
        index_ = 0;  
    }  
public:  
    static std::string INDEX;  
    static std::string TO;  
    static std::string FROM;  
    static std::string MSG;  
    static std::string SPLITTER;  
    static std::string TAG;  
private:  
    int index_;  
    std::string to_;  
    std::string from_;  
    std::string msg_;  
      
public:  
    sms_info(int index, const std::string& to, const std::string& from, const std::string& msg)  
    {  
        index_ = index;  
        to_ = to;  
        from_ = from;  
        msg_ = msg;  
    }  
    int index()  
    {  
        return index_;  
    }  
    std::string to()  
    {  
        return to_;  
    }  
    std::string from()  
    {  
        return from_;  
    }  
    std::string msg()  
    {  
        return msg_;  
    }  
};  
  
class json_parser  
{  
private:  
    static std::string ROOTNAME;  
public:  
    static std::string generate(const std::vector& smss);  
    static bool parse(const std::string& s, std::vector& smss);  
public:  
    static void tester();  
};  
#endif /* defined(__mongoose__json_parser__) */    
  
//  
//  json_parser.cpp  
//  mongoose  
//  
//  Created by Alex on 5/26/14.  
//  Copyright (c) 2014 Cenbong. All rights reserved.  
//  
  
#include "json_parser.h"  
#include   
#include "sstream"  
#include   
#include   
#include   
#include   
#include   
std::string sms_info::INDEX = "index";  
std::string sms_info::TO = "to";  
std::string sms_info::FROM = "from";  
std::string sms_info::MSG = "msg";  
std::string sms_info::SPLITTER = ",";  
std::string sms_info::TAG = "SMSInfo";  
  
std::string json_parser::ROOTNAME = "smss";  
void json_parser::tester()  
{  
    std::vector smss1;  
    for(int i = 0; i < 5; i++)  
    {  
        int index = i;  
        std::string to = "1860000" ;  
        std::string from = "1880000" ;  
        std::string msg = "这个短信发给Alex,   谢谢。 ";  
        smss1.push_back(sms_info(index, to, from, msg));  
    }  
    std::string s = generate(smss1);  
    std::vector smss2;  
    parse(s, smss2);  
    assert(smss1.size() == smss2.size());  
}  
std::string json_parser::generate(const std::vector& smss)  
{  
    boost::property_tree::ptree pt_root;  
    boost::property_tree::ptree children;  
    boost::property_tree::ptree child;  
      
    for(size_t i = 0; i < smss.size(); i++)  
    {  
        sms_info sms = smss.at(i);  
        child.put(sms_info::INDEX, sms.index());  
        child.put(sms_info::TO, sms.to());  
        child.put(sms_info::FROM, sms.from());  
        child.put(sms_info::MSG, sms.msg());  
        children.push_back(std::make_pair("", child));  
    }  
      
    pt_root.add_child(ROOTNAME, children);  
    std::stringstream ss;  
    boost::property_tree::write_json(ss, pt_root);  
    std::string s = ss.str();  
    return s;  
}  

bool json_parser::parse(const std::string& s, std::vector& smss)  
{  
    std::istringstream iss;  
    iss.str(s.c_str());  
    boost::property_tree::ptree parser;  
    boost::property_tree::json_parser::read_json(iss, parser);  
    boost::property_tree::ptree sms_array = parser.get_child(ROOTNAME);  
    BOOST_FOREACH(boost::property_tree::ptree::value_type &v, sms_array)  
    {  
        boost::property_tree::ptree p = v.second;  
        int index = p.get(sms_info::INDEX);  
        std::string to = p.get(sms_info::TO);  
        std::string from = p.get(sms_info::FROM);  
        std::string msg = p.get(sms_info::MSG);  
          
        smss.push_back(sms_info(index, to, from, msg));  
    }  
    return true;  
}

  
========

C++ 之Boost 实用工具类及简单使用

http://www.cnblogs.com/kunhu/p/3681275.html


本文将介绍几个 Boost 实用工具类,包括 tuple、static_assert、pool、random 和 program_options
等等。需要对标准 STL 具备一定的了解才能充分理解本文的内容。
1.boost::tuple 类
有时,希望 C++ 函数返回多个不相关的值。在推出 STL 之前,实现此目的的方法是创建所有不相关变
量的结构,并以指针或引用的形式返回它们或作为参数传递给函数——但是任一种方法都不是表达程序
员意图的方法。STL引入了 pair,可将其用于聚合不相关的数据部分,但它一次只能处理两个数据对象
。为了使用 int、 char 和 float 的元组(tuple ),可以按如下方式返回 pair:
make_pair > (3, make_pair ('a', 0.9));
随着您添加更多的元素,创建元组结构将变得越来越困难。Boost tuple 类型派上了用场。要使用 
boost::tuple,必须包括头文件 tuple.hpp。要执行元组比较和组 I/O,您需要分别包括 
tuple_comparison.hpp 和tuple_io.hpp。
第一个使用元组的程序
清单 1 使用 int、char 和 float 的元组并打印内容。

清单 1. 创建 Boost 元组并打印内容

#include

#include 
#include 
#include 
using namespace boost;
int main ( )
{
 tuple t(2, 'a', 0.9);
  std::cout << t << std::endl;
 return 0;
}

此代码的输出为 (2 a 0.9)。请注意,<< 运算符重载 std::ostream,以便通过转储每个单独的 tuple 

元素来输出元组。
与元组相关的重要事实
在使用元组时,务必牢记以下事实:
能够形成元组的元素数量目前仅限于 10 个。
元组可以包含用户定义的类类型,但是您必须负责确保那些类已经定义了正确的构造函数和拷贝构造函
数 (copy constructor)。清单 2 显示了产生编译时错误的代码部分,因为该拷贝构造函数是私有的。

清单 2. 用于元组的类必须具有正确的拷贝构造函数

#include

#include 
#include 
#include 
using namespace std;
class X
 {
 int x;
 X(const X& u) { x = u.x; }
 public:
  X(int y=5) : x(y) { }
};

int main ( )
{
 boost::tuple t(3, X(2));
 return 0;
}


与 STL 提供的 make_pair 函数非常类似,Boost 提供了 make_tuple 例程。要从函数返回元组,您必
须调用make_tuple。可以创建具有临时元素的元组;清单 3 的输出为 (4 0)。

清单 3.使用 make_tuple 来从函数返回元组


#include 
#include 
#include 
#include 
using namespace std;
boost::tuple
divide_and_modulo(int a, int b)
{
 return boost::make_tuple (a/b, a%b);
}

int main ( )
{
  boost::tuple t = divide_and_modulo(8, 2);
 cout << t << endl;
 return 0;
}

要访问元组的各个元素,您可以使用 get 例程。此例程具有两种变体,如清单 4 所示。请注意,还可

以使用 get 例程来设置元组的各个元素,虽然有些编译器可能不支持此功能。

清单 4. 使用 boost::get 例程

#include 
#include 
#include 
#include 
using namespace std;
boost::tuple
divide_and_modulo(int a, int b)
{
 return boost::make_tuple (a/b, a%b);
}

int main ( )
{
  boost::tuple t = divide_and_modulo(8, 2);
 cout << t.get<0> () << endl; // prints 4
 cout << boost::get<1>(t) << endl; // prints 0
 boost::get<0>(t) = 9; // resets element 0 of t to 9
  ++boost::get<0>(t);  // increments element 0 of t
 cout << t.get<1>() << endl; // prints 10
 return 0;
}

可以使用 const 限定符来声明元组,在这种情况下,用于访问特定元素的 get 调用将返回对 const 的

引用。不能对以这种方式访问的元素进行赋值(请参见清单 5)。

清单 5. 使用 const 限定符来声明的元组不可修改


#include 
#include 
#include 
#include 
using namespace std;
int main ( )
{
 const boost::tuple t(8, "Hello World!");
 t.get<1> ()[0] = "Y"; // error!
 boost::get<0>(t) = 9; // error!
 return 0;
}

可以使用关系运算符 ==、!=、<、>、<= 和 >= 对相同长度的元组进行比较。比较不同长度的元组会产

生编译时错误。这些运算符的工作原理是从左到右地比较两个参与元组的每个单独的元素(请参见清单 

6)。

清单 6. 关系运算符与元组


#include 
#include 
#include 
#include 
#include 
using namespace std;
int main ( )
{
 boost::tuple t(8, string ("Hello World!"));
 boost::tuple t2(8, string("Hello World!"));
  cout << (t == t2) << endl;
 boost::tuple r(9, string ("Hello World!"));
 boost::tuple r2(8, string("Hello World!"));
  cout << (r > r2) << endl;
 boost::tuple q(string ("AA"), string("BB"));
 boost::tuple q2(string("AA"), string ("CC"));
 cout << (q < q2) << endl;
 return 0;
}


清单 6 的输出为 1 1 1。请注意,如果您不是使用 string 或 int,而是使用没有定义 ==、!= 等运算

符的用户定义的随机类,则会产生编译错误。
2.Boost 静态断言
断言是 C/C++ 中的防错性程序设计的一部分。最常见的用法如下:
assert();
assert 例程仅在调试模式下有效。在发布模式下,通常使用预处理器宏 ¨CDNDEBUG 来编译代码,其效
果相当于assert 不存在。静态断言建立在这个基本概念之上,只不过静态断言仅在编译时有效。此外,
静态断言不生成任何代码。
例如,假设您在一个整型变量中执行某个位操作,并预期其大小为 4:这并非在所有操作系统平台上都
是如此(请参见清单 7)。

清单 7. 使用 Boost 静态断言来验证变量的大小


#include 
int main ( )
{
  BOOST_STATIC_ASSERT(sizeof(int) == 4);
  // … other code goes here
 return 0;
 }


要使用 BOOST_STATIC_ASSERT 宏,您必须包括 static_assert.hpp 头文件。不需要诸如 DNDEBUG 等特

定于编译器的选项,并且您不需要向链接器提供库——单凭该头文件就足够了。
如果断言有效,则代码将顺利编译。但是如果该假设无效,在某些 64 位平台上就可能是如此,则编译
器将生成错误消息并停止。使用 g++-3.4.4 进行编译时的典型消息如下:
assert.cc: In function `int main()':
assert.cc:8: error: incomplete type `boost::STATIC_ASSERTION_FAILURE< false>'
  used in nested name specifier
这肯定不是最详细的错误消息,但是它指出了具有错误假设的函数和确切行号。
下面是一些典型的现实情景,您应该在其中考虑使用静态断言:
静态声明的数组的边界检查
验证原始和用户定义的变量的大小
允许模板类或函数仅使用某些数据类型来进行实例化
Boost 静态断言的行为
您可以在类、函数或命名空间范围中使用 Boost 静态断言;还可以与模板一起使用它们。清单 8 中的

示例阐明了概念。


清单 8. 使用 Boost 静态断言来限制类实例化

#include 
#include 
using namespace std;
using namespace boost;

template
class A
{
  private:
  T x, y;
  BOOST_STATIC_ASSERT(numeric_limits::is_signed);
 public:
  A(T x1, T y1) : x(x1), y(y1) { }
};

int main ( )
{
  A a(2, 1);
 return 0;
}


在清单 8 中,仅当 T 有符号时,模板类 A 才能进行实例化。类 numeric_limits 是标准命名空间的一
部分;它检查基本类型在给定操作系统平台上的属性。在无符号(unsigned )的 long 类型的情况下,
专用变体numeric_limits 的 is_signed 标志为 false。当您在类范围中使用 

BOOST_STATIC_ASSERT时,它是私有的、受保护的还是公开的并不重要。

清单 9 将 BOOST_STATIC_ASSERT 与函数结合在一起使用。该代码确保在函数 f1 中处理的类型只能是 

A 类型或其派生类型。通过使用 Boost 的静态断言宏和 is_convertible 例程(在

boost/type_traits/is_convertible.hpp 中定义),此代码确保不希望的类型不会最终调用此例程。

清单 9. 将函数限制为仅处理特定的数据类型

#include 
#include 
#include 
using namespace std;
using namespace boost;
struct A
{
 int a;
 float b;
};
struct B : public A
 {
};
template 
int f1 (T y)
{
 BOOST_STATIC_ASSERT ((is_convertible::value));
 return 0;
}

int main ( )
{
  f1 (new B);
 return 0;
}


3.使用 Boost 库生成随机数
随机数生成用于各种各样的计算机应用,例如安全和游戏。UNIX 系统一般附带了随机数生成例程 rand 
和 srand。通常,srand 使用新的种子值来初始化 rand(请参见清单 10)。

清单 10. 用于在传统 UNIX 中生成随机数的代码


#include 
#include 
int main ( )
{
  srand(time(NULL)); // this introduces randomness
 for (int i=0; i<10; i++)
   printf("%d\n", rand());
 return 0;
}


rand 例程返回一个介于 0 和 stdlib.h 中定义的 RAND_MAX 之间的数字。要了解 srand 所做的工作,
可以在将srand 例程注释掉的情况下编译清单 11。当您这样做时,您将观察到 rand 并不真正是随机的
——可执行代码每次打印同一组值。为了在代码中引入随机性,您可以使用 srand,此例程使用种子值
来初始化 rand。由于每次调用程序时的时间值是不同的,因此对于不同的调用,代码打印的值不同。
使用 Boost 随机数生成器
Boost 随机数生成器位于 boost/random 文件夹中。此外,为方便起见,boost/ 目录中的 random.hpp 
头文件包括了 boost/random 文件夹中的所有其他头文件。
Boost 随机接口划分为两个部分:随机数生成器和随机数必须位于其中的分布。本文讨论 uniform_int 
和uniform_real random-number 分布以及 mt19937 随机数生成器。清单 11 使用了 uniform_int 和

uniform_real 分布。


清单 11. 将 variate_generator 与 mt19937 引擎和 uniform_int 分布一起使用


#include 
#include 
using namespace std;
using namespace boost;
int main ( )
{
 uniform_int<> distribution (1, 100) ;
 mt19937 engine ;
 variate_generator > myrandom (engine, distribution);
 for (int i=0; i<100; ++i)
  cout << myrandom() << endl;
 return 0;
}


此代码生成介于 1 和 100 之间(包括 1 和 100)的随机数;用于实现随机化的基础引擎是 mt19937。


variate_generator 为您组合了该引擎和分布。
清单 12 使用了另一个引擎: kreutzer1986.

清单 12:组合 uniform_real 分布和 kreutzer1986 引擎


#include 
#include 
using namespace std;
using namespace boost;
int main ( )
{
 uniform_real<> distribution(1, 2) ;
 kreutzer1986 engine ;
 variate_generator > myrandom (engine, distribution);
 for (int i=0; i<100; ++i)
  cout << myrandom() << endl;
 return 0;
}


除了 uniform_int 和 uniform_real 分布以外,Boost 还提供了几个其他分布,包括二项式、泊松和正
态分布。
4.boost::pool 库概述
Boost pool 库引入了可用于实现快速内存分配的工具。正确的内存块对齐可以得到保证。
根据 Boost 文档所述,当您分配和释放许多小型对象时,建议使用池。使用池的另一个不太明显的优点
在于,作为程序员,您不必担心内存泄露:内存由 Boost 库在内部自动进行管理。要使用 pool 库,您
不必在链接时提供特定的库——单凭头文件就足以完成链接了。
有多个接口对 pool 库可用:
池接口——替代 malloc 进行工作的普通接口。要使用此接口,需要包括 boost/pool 文件夹中的 
pool.hpp 头文件。
对象池接口——有对象意识的接口,在对象创建和删除过程中分别相应地调用构造函数和析构函数。还
可以使用此接口创建普通对象,而不调用它们的构造函数。接口定义是在位于 boost/pool 目录中的 
object_pool.hpp 头文件中提供的。清单 13 引入了 pool 和 object_pool 接口。请注意以下几点:
pool 接口需要知道每个单独的元素而不是类型的大小,因为它是一个 malloc 风格的分配程序,不会调
用构造函数。
pool 接口中的 malloc 例程返回 void*。
object-pool 接口需要类型信息,因为要调用构造函数。
object-pool 接口中的 malloc/construct 例程返回指向类型的指针。malloc 例程不调用构造函数,但
是construct 要调用构造函数。
使用 pool 接口或 object-pool 接口来创建的元素的范围与从中创建它们的池的范围相同。
要从池接口中释放内存,可以调用 purge_memory 方法。该方法释放您先前创建的内存块,并使得从分
配程序例程返回的所有指针失效。
要释放各个元素,可以调用 pool 接口中的 free 例程。例如,如果 t 是使用 pool 接口来创建的池,
并且 m 是从 t分配的指针,则 t.free(m) 将把内存返回给 t(将其添加到 t 的空闲内存列表)。

清单 13. pool 和 object_pool 接口

#include 
#include 
#include 
using namespace std;
using namespace boost;
class A
{
 public: A( ) { cout << "Declaring An"; }
     ~A( ) { cout << "Deleting An"; }
};

int main ( )
{
 cout << "Init pool...n";
 pool<> p(10 * sizeof(A));
 for (int i=0; i<10; ++i)
  A* a = (A*) p.malloc(); // Always returns sizeof(A)
 p.purge_memory();
 cout << "Init object pool...n";
 object_pool q;
 for (int i=0; i<10; ++i)
  A* a = q.construct(); // Calls A's constructor 10 times
 return 0;
}


singleton_pool 接口——与 pool 接口几乎相同,但是用作独立池。独立池的底层结构具有为 malloc
、free 等声明的静态成员函数,并且构造函数是私有的。独立池声明中的第一个参数称为标记— —它
允许存在不同的独立池集(例如,用于 int 的多个池,其中每个池服务于不同的目的)。必须包括 

singleton_pool.hpp 头文件才能使用此接口。请参见清单 14。

清单 14. singleton_pool 接口

#include 
#include 
using namespace std;
using namespace boost;
struct intpool { };
struct intpool2 { };
typedef boost::singleton_pool ipool1;
typedef boost::singleton_pool ipool2;

int main ( )
{
 cout << "Init singleton pool...n";
 for (int i=0; i<10; ++i) {
  int* q1 = (int*) ipool1::malloc();
  int* q2 = (int*) ipool2::malloc();
}

    ipool1::purge_memory();
 ipool2::purge_memory();
 return 0;
}


pool_alloc 接口——通常与 STL 容器结合在一起使用。请考虑以下代码片段: #include 


std::vector > v;
std::list > L;
存在两个分配程序:pool_allocator 和 fast_pool_allocator。第一个分配程序是通用分配,可以满足

针对任何数量的连续内存块的请求。fast_pool_allocator 最适合于一次请求单个(通常较大)块,但

是也适用于通用分配,不过具有一些性能缺点。
5.boost::program_options 简介
命令行处理是另一个难点,开发人员通常不会采用结构化的方式来解决。其结果是从头到尾维护开销。

Boost program_options 库提供了简化命令行处理的例程和数据结构。
清单 15 详细描述了 boost::program_options 的使用。这是建议在您的代码中使用的标准模板。

清单 15. 使用 boost::program_options


#include 
#include 
#include 
using namespace std;
int main (int ac, char* av[])
{
 boost::program_options::options_description options("command line options");
 options.add_options() ("help", "Use -h or --help to list all arguments")
                   ("file", boost::program_options::value (),
                    "Provide input file name");
  boost::program_options::variables_map vmap;
 boost::program_options::store(
    boost::program_options::parse_command_line(ac, av, options), vmap);
  boost::program_options::notify(vmap);
 if (vmap.count("help")) {
   cout << options << endl;
 }
 return 0;
}


您必须包括 program_options.hpp 头文件。清单 15 的工作方式如下:
options_description 类声明所有的有效命令行选项。
使用方法 add_options,您可以注册命令和跟在命令后面的参数类型。在此例中,help 选项不需要任何

参数,但是file 选项需要一个字符串参数。
variables_map 类在运行时存储命令行选项及其参数。
Boost 的 parse_command_line 例程解析 argc 和 argv 参数。store 和 notify 方法帮助存储 vmap 

对象中的数据。
当您检查 help 是否为程序的恰当命令行选项(这是 vmap.count("help") 所做的工作)时,options 

对象将被转储到 cout。这意味着运算符 << 是为 options_description 类定义的。
下面是来自清单 15 的输出:
[user@/home/user1] ./a.out --help
command line options:
 --help         Use -h or --help to list all arguments
 --file arg      Provide input file name
当您遇到其他选项时,可以采取进一步的操作。例如,下面的代码片段经过了修改,以打印您输入的文

件名:

if (vmap.count("file")) {
   cout << "Setting input file to " << vmap["file"].as() << ".n";
} else {
   cout << "No file specifiedn";
}

请注意,variable_map 类在许多方面与哈希表非常相似。例如,要检索 file 参数,您可以调用 vmap

["file"]。
提供多个参数和缩写的命令选项
命令行处理通常同时需要同一个命令选项的短名称和长名称。此外,您通常必须多次使用某个选项,以
便收集该选项的所有参数。例如,您可能希望使用 ¨Ch 和 ¨Chelp 来打印可用的命令。清单 16 演示

了这些功能。


清单 16. 使用较短的选项变体并允许多次调用命令选项
#include 
#include 
#include 
using namespace std;
int main (int ac, char* av[])
{
 boost::program_options::options_description options("command line options");
 options.add_options() ("help,h", "Use -h or --help to list all arguments")
          ("file", boost::program_options::value >( ),
             "Provide input file name");
  boost::program_options::variables_map vmap;
 boost::program_options::store(
    boost::program_options::parse_command_line(ac, av, options), vmap);
  boost::program_options::notify(vmap);
 if (vmap.count("help")) {
   cout << options << endl;
 }
 if (vmap.count("file")) {
   vector ifiles(vmap["file"].as< vector > ());
    vector::iterator vI;
   cout << "Number of input files: " << ifiles.size() << endl;
   cout << "Input file list: " << endl;
   for(vI = ifiles.begin(); vI != ifiles.end(); ++vI)
     cout << "t" << *vI << endl;
 } else {
   cout << "No file specifiedn";
  }
 return 0;
}


在使用 add_options 来添加命令选项时,较长和较短的选项之间使用逗号进行分隔。请注意,较长的选

项 (help)必须在较短的选项 (h) 之前,代码才能正常工作。与使用单个字符串不同,file 选项现在是

使用一个字符串向量来定义的。如果指定了 ¨Cfile 选项多次,则会将在所有指定中收集到的命令选项

参数存储在关联的 vector中。下面是使用不同的参数来多次指定 ¨Ch 和 ¨Cfile 所获得的

输出:
[user@/home/user1] ./a.out -h
command line options:
-h [ --help ] Use -h or --help to list all arguments
--file arg Provide input file name
No file specified
[user@/home/user1] ./a.out --file abc --file pqr
Number of input files: 2
Input file list:
abc
pqr
解析位置选项
带输入参数但是不带命令行选项来调用某个程序是非常普遍的。您预期参数和命令行选项之间自动存在

某种神奇关联。这种行为由 boost::program_options 提供支持。
请考虑清单 17。第一个参数转换为 --file=,第二个参数转换为 --do- 

file=

清单 17. 将位置参数与命令行选项相关联

#include 
#include 
#include 
using namespace std;
int main (int ac, char* av[])
{
boost::program_options::options_description options("command line options");
options.add_options() ("help,h", "Use -h or --help to list all arguments")
("file", boost::program_options::value(),
"Provide input file name")
("do-file", boost::program_options::value(),
"Specify commands file");
boost::program_options::variables_map vmap;
boost::program_options::positional_options_description poptd;
poptd.add ("file", 1);
poptd.add("do-file", 2);
boost::program_options::store(
boost::program_options::command_line_parser(ac, av).
options(options).positional(poptd).run(), vmap);
boost::program_options::notify(vmap);
if (vmap.count("file")) {
cout << "file: " << vmap["file"].as ( ) << endl;
}
if (vmap.count("do-file")) {
cout << "do- file: " << vmap["do-file"].as ( ) << endl;
}
return 0;
}


下面是输出内容:
[user@/home/user1] ./a.out file1 dofile1
file: file1
do-file: dofile1
清单 15 中使用的某些 API 在清单 17 中已发生更改。清单 17 引入了新的类 

positional_options_description。该类的 add 方法(add("command option", N))将位置 N 处的输

入参数与命令行选项 "command option" 相关联。因此,./a.out file1 在内部解析为 ./a.out 

¨Cfile=file1。另一个区别在于调用 program_options::store方法的方式。与使用 

parse_command_line 例程不同,Boost 库要求您将 command_line_parser 例程与store 方法结合在一

起使用。
请注意,仍然可以使用 ¨Cfile 和 ¨Cdo-file 选项来调用该程序。最后,若要将所有的输入参数与同

一个命令行选项相关联,您需要使用值 -1 将该命令行选项添加到 positional_options_description 

对象。下面是代码:

boost::program_options::positional_options_description poptd;
poptd.add ("file", -1);
========

boost::algorithm的几个简单例子

http://blog.csdn.net/huang_xw/article/details/8451442

void test_foreach()  
{  
    using namespace boost::assign;  
    std::vector v;  
    v += 1, 2, 3, 4, 5, 6, 7, 8, 9;  
  
    BOOST_FOREACH(int x, v)  
    {  
        std::cout << x << ", ";  
    }  
    std::cout << std::endl;  
  
    std::string str("boost foreach");  
    BOOST_FOREACH(char& x, str)  
    {  
        std::cout << x << "-";  
    }  
    std::cout << std::endl;  
}  
  
void test_minmax()  
{  
    struct Comp  
    {  
        bool operator()(const std::string &a, const std::string &b)  
        {  
            return (a < b) || (b.find("BOSS") != std::string::npos);  
        }  
    };  
  
    std::string s1("5000"), s2("123BOSS");  
    BOOST_AUTO(x, minmax(s1, s2));  
    std::cout << x.second << " " << x.first << std::endl;  
    BOOST_AUTO(y, minmax(s1, s2, Comp()));  
    std::cout << y.second << " " << y.first << std::endl;  
}  
  
void test_minmax_element()  
{  
    std::vector v = boost::assign::list_of(633)(90)(67)(83)(2)(100);  
    BOOST_AUTO(x, boost::minmax_element(v.begin(), v.end()));  
  
    std::cout << "min: " << *x.first << std::endl;  
    std::cout << "max: " << *x.second << std::endl;  
}  



========

boost c++库学习实例

http://blog.csdn.net/earbao/article/details/17398939


1、Linux下载编译boost源码:
./bootstrap.sh
sudo ./bjam --layout=versioned --build-type=complete  install 
2、测试实例:
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
#include  
#include  
#include  
#include  
#include  
#include  
#include  
using namespace std;  
using namespace boost;  
  
void test001() {  
    std::vector v(100);  
    std::ofstream fs;  
    progress_display pd(v.size());  
  
    std::vector::iterator it;  
    for (it = v.begin(); it != v.end(); ++it) {  
        fs << *it << std::endl;  
        ++it;  
        cout << "*";  
        //sleep(1);  
    }  
    cout << endl;  
}  
#include  
#include  
  
void test002() {  
    boost::gregorian::date d(2010, 1, 30);  
    std::cout << d.year() << std::endl;  
    std::cout << d.month() << std::endl;  
    std::cout << d.day() << std::endl;  
    std::cout << d.day_of_week() << std::endl;  
    std::cout << d.end_of_month().day() << std::endl;  
}  
#include  
  
class Shared {  
public:  
  
    Shared() {  
        std::cout << "ctor() called" << std::endl;  
    }  
  
    Shared(const Shared & other) {  
        std::cout << "copy ctor() called" << std::endl;  
    }  
  
    ~Shared() {  
        std::cout << "dtor() called" << std::endl;  
    }  
  
    Shared & operator =(const Shared & other) {  
        std::cout << "operator = called" << std::endl;  
    }  
};  
  
void test003() {  
    typedef boost::shared_ptr SharedSP;  
    typedef std::vector VShared;  
    VShared v;  
    v.push_back(SharedSP(new Shared()));  
    v.push_back(SharedSP(new Shared()));  
}  
#include   
//字符串转换为整形  
  
void test004(string str) {  
    int i = boost::lexical_cast(str);  
    cout << i << endl;  
}  
#include   
  
void test_format() {  
    // 使用%序号%的方式给出指示符, 后面用%连接对应的数据。  
    cout << boost::format("writing %1%,  x=%2% : %3%-th try") % "toto" % 40.23 % 50 << 


endl;  
    // 输出:writing toto,  x=40.23 : 50-th try  
    // 可以延迟使用,顺序不必一致  
    boost::format fmter("%2% %1%");  
    fmter % 36;  
    fmter % 77;  
    cout << fmter << endl;  
    // 输出:77 36  
  
    // 可重用  
    fmter % 12;  
    fmter % 24;  
    cout << fmter << endl;  
    // 输出:24 12  
  
    // 可直接转成字符串  
    std::string s = fmter.str();  
    std::string s2 = str(boost::format("%2% %1% %2% %1%") % "World" % "Hello");  
  
    cout << s << endl << s2 << endl;  
    // 输出:  
    // 24 12  
    // Hello World Hello World  
  
    // 可以使用printf指示符  
    cout << boost::format("%3.1f - %.2f%%") % 10.0 % 12.5 << endl;  
    // 输出:10.0 - 12.50%  
  
    // printf指示符里使用N$指定使用第几个参数  
    cout << boost::format("%2$3.1f - %1$.2f%%") % 10.0 % 12.5 << endl;  
    // 输出:12.5 - 10.00%  
}  
#include  
  
void test005() {  
    string str("readme001readme002readme.txt");  
    if (ends_with(str, "txt")) {  
        cout << to_upper_copy(str) + " UPPER" << endl;  
        assert(ends_with(str, "txt"));  
    }  
    replace_first(str, "readme", "followme");  
    replace_all(str, "readme", "hehe");  
    cout << str << endl;  
    vector v(str.begin(), str.end());  
    vector v2 = to_upper_copy(erase_first_copy(v, "txt"));  
    for (int i = 0; i < v2.size(); ++i) {  
        cout << v2[i];  
    }  
    cout << endl;  
}  
#include   
  
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 << "-";  
    }  
    cout << endl;  
}  
#include  
#include  
//需要编译器加上 -lboost_regex  
//使用cppunit需要连接器加上 -lncurses -lcppunit -ldl  
void test006() {  
  
    regex reg("a.c");  
    assert(regex_match("abc", reg));  
    //assert(regex_match("a + c", reg));  
    assert(!regex_match("ac", reg));  
    assert(!regex_match("abd", reg));  
  
    boost::regex reg2("\\d{3}([a-zA-Z]+).(\\d{2}|N/A)\\s\\1");  
    std::string correct = "123Hello N/A Hello";  
    std::string incorrect = "123Hello 12 hello";  
    assert(boost::regex_match(correct, reg2) == true);  
    assert(boost::regex_match(incorrect, reg2) == false);  
}  
  
#include   
  
void test_any() {  
    typedef std::vector 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() << "=";  
        try {  
            int result = any_cast(a[i]);  
            cout << result << endl;  
        } catch (boost::bad_any_cast & ex) {  
            cout << "cast error:" << ex.what() << endl;  
        }  
    }  
}  
  
#include  
  
void hello() {  
    std::cout << "Hello world, I'm a thread!" << std::endl;  
}  
//编译需要加上-lboost_system -L/usr/local/lib -lboost-thread  
//-lboost_thread -lboost_system   
//如果报错error while loading shared libraries: libboost_thread.so.1.49.0: cannot open 


shared object file: No ,  
//则使用sudo ldconfig /home/shaochangqing/study/boost_1_49_0/stage/lib 或者export PATH=


${PATH}:/usr/local/lib:/usr/local/include  
  
int test_Thread() {  
    boost::thread thrd(&hello); // 译注:hello前面的&符号,可要可不要  
    thrd.join();  
    return 0;  
}  
  
//extern bool httpGet(/*out*/string& result, const string& host, uint16_t port, const 


string& url, boost::asio::io_service &_io);  
  
/** 本程序基于boost1_55_0*/  
int main(int argc, char** argv) {  
  
    test_Thread();  
    test001();  
    test002();  
    test003();  
    test004("123456");  
    test_format();  
    test005();  
    test_tokenizer();  
    test006();  
    test_any();  
    /**boost::asio::io_service io; 
    string str; 
    httpGet(str,"http://www.baidu.com/",80,"index.html",io); 
    cout<     printf("\nok\n");  
    return 0;  

========

c++ boost 汉字和模式串混用的例子

http://www.cnblogs.com/finallyliuyu/p/3745097.html


*===============================================================
*   Copyright (C) 2013 All rights reserved.
*   
*   文件名称:StringProcess.cpp
*   创 建 者:
*   创建日期:2013年04月24日
*   描    述:
*   备    注: 
*   更新日志:
*
================================================================*/
#include
#include
#include 
#include
#include
#include
#include "boost/regex.hpp"
#include  
#include
#include
// please add your code here!
using namespace std;
#define MAX_LINE_LENGTH 1048576
#define TAGLEN 50
/************************************************************
* @brief Author:刘禹 finallyly 20130425 去掉字符串首尾空格
==================================================
* @param s
==================================================
**********************************************************/
void trim(char *s)
{
    char *start;
    char *end;
    int len=strlen(s);
    start=s;
    end=s+len-1;
    while(1)
    {
        char c=*start;
        if(!isspace(c))
        {
            break;
        }
        start++;
        if(start>end)
        {
            s[0]='\0';
            return ;
        }
    }
    while(1)
    {
        char c=*end;
        if(!isspace(c))
        {
            break;
        }
        end --;
        if(start>end)
        {
            s[0]='\0';
            return;
        }
    }
    memmove(s,start,end-start+1);
    s[end-start+1]='\0';
    return;
}


inline bool strTolower( char* str )
{
    if ( !str )
        return false;
    int i = 0;
    bool flag = true;
    while ( str[i] )
    {
        if ( 'A' <= str[i] && 'Z' >= str[i] )
        {
            str[i] += 32;
        }
        else if ( 'a' <= str[i] && 'z' >= str[i] )
        {
        }
        else
        {
            flag = false;
        }
        ++i;
    }
    return flag;
}


/************************************************************
* @brief Author:刘禹 finallyly
* 从系统默认的汉字编码本机是GBK转unicode,宽字符保存
==================================================
* @param sToMatch
==================================================
* @return 
**********************************************************/
wstring String2Wstring(string sToMatch)
{     
    wstring wsToMatch;
    setlocale( LC_CTYPE, "" ); // 很重要,没有这一句,转换会失败。   
    int iWLen = mbstowcs( NULL, sToMatch.c_str(), sToMatch.length() ); // 计算转换后宽字符


串的长度。(不包含字符串结束符)
    if(iWLen>0)
    {
        wchar_t *lpwsz = new wchar_t[iWLen + 1];  
        int i = mbstowcs( lpwsz, sToMatch.c_str(), sToMatch.length() ); // 转换。(转换后的


字符串有结束符)   
        wsToMatch.assign(lpwsz);  
        delete []lpwsz;  
    }
    else
    {
        wsToMatch=L"";    
    }
    return wsToMatch;
}  
/************************************************************
* @brief Author:刘禹 finallyly
* Unicode转系统自带编码,用于输出
==================================================
* @param sToMatch
==================================================
* @return 
**********************************************************/
string Wstring2String(wstring sToMatch)  
{     
    string sResult;
    int iLen = wcstombs( NULL, sToMatch.c_str(), 0 ); // 计算转换后字符串的长度。(不包含字


符串结束符)   
    if(iLen>0)
    {
        char *lpsz = new char[iLen + 1];  
        int i = wcstombs( lpsz, sToMatch.c_str(), iLen ); // 转换。(没有结束符)   
        lpsz[iLen] = '\0';  
        sResult.assign(lpsz); 
        delete []lpsz;  
    }
    else
    {
        sResult="";
    }
    return sResult;  
}
/************************************************************
* @brief Author:刘禹 finallyly
* 从指定编码转换到目标编码
==================================================
* @param toCode
==================================================
* @param fromCode
==================================================
* @param srcstr
==================================================
* @param deststr
==================================================
* @param srclen
==================================================
* @param destlen
==================================================
* @return 
**********************************************************/
int toAnotherCode(const char *toCode,const char *fromCode,char *srcstr, char *deststr, 


size_t srclen,size_t &destlen)
{
    iconv_t convertor=iconv_open(toCode,fromCode);
    size_t inputsize;
    size_t outputsize;
    size_t oldoutputsize;
    char *input, *inputold;
    char *output=NULL;
    char *outputold=NULL;
    int flag=0;
    if(convertor==iconv_t(-1))
    {
        fprintf(stderr,"convertor device initailization failed!\n");
        return 1;
    }
    else
    {
        inputsize=srclen;
        input=new char[inputsize+1];
        memcpy(input,srcstr,inputsize);
        input[inputsize]='\0';
        inputold=input;
        outputsize=inputsize*5;
        oldoutputsize=outputsize;
        output=new char[outputsize];
        output[0]=0;
        outputold=output;
        size_t rc = iconv(convertor,&input,&inputsize,&output,&outputsize);
        memcpy(deststr,outputold,oldoutputsize-outputsize);
        deststr[destlen]=0;
        destlen=oldoutputsize-outputsize;
        if(rc>0)
        {
            flag=1;
        }
        
        delete []inputold;
        delete []outputold;


    }
    iconv_close(convertor);
    if(flag==1)
    {
        return 0;
    }
    else
    {
        return 1;
    }


}
/************************************************************
* @brief Author:刘禹 finallyly 20130424
==================================================
**********************************************************/
void PrintUsage()
{
    fprintf( stderr, "prog [IN]hzpylist_file [IN]input_file [OUT]output_file [OUT]


errdmp_file\n" );
}
void testRegex()
{
    string s="刘禹,刘德华,刘佳佳。。。王大虎。。。刘长春,xixi";
    string t="刘[^刘]*?,";
    wstring p=String2Wstring(t);
    wstring ws=String2Wstring(s);
    boost::wregex wreg(p,boost::regbase::icase|boost::regex::perl);
    boost::wsmatch wm;
    vector results;
    wstring::const_iterator  it=ws.begin();
    wstring::const_iterator  end=ws.end();
    while(boost::regex_search(it,end,wm,wreg))
    {
        wstring wtemp=wm[0];
        string temp=Wstring2String(wtemp);
        results.push_back(temp);
        it=wm[0].second;
    }
    fprintf(stdout,"输出正则匹配结果\n");
    for(vector::iterator it=results.begin();it!=results.end();it++)
    {
            printf("%s\n",(*it).c_str());
    }
}
int LoadFile(char* inputfile)
{
    FILE *fin = NULL;
    char line[102400] = {0};
    char word[102400] = {0};
    int len = 0;
    fin = fopen(inputfile, "r");
    if (NULL == fin)
    {
        fprintf(stderr,"LoadAddress can not open inputfilename %s\n", inputfile);
        return 1;
    }
    
    while(true)
    {
        fgets(line, 102400, fin);
        if (feof(fin))
        {
            break;
        }
        len = strlen(line);
        if (0 == line[0] || '\n' != line[len - 1])
        {
            continue;
        }
        line[len - 1] = 0;
        string pattern ="首都或首府:";
        string p1="([\u2E80-\u9FFF])+";
        wstring wp1 = String2Wstring(p1);
        //wstring wpattern = L"([\u2E80-\u9FFF])+";
        wstring wpattern = L"([\u2E80-\u9FFF]+)"+String2Wstring(pattern)+L"([\u2E80-


\u9FFF]+)";
        wstring winputstr = String2Wstring(line);
        boost::wregex wreg(wpattern, boost::regex::perl|boost::regbase::icase);
        boost::smatch what;
        boost::wsmatch wswhat;
        wstring::const_iterator wstrit = winputstr.begin();
        wstring::const_iterator wstrend = winputstr.end();
        while (boost::regex_search(wstrit, wstrend, wswhat, wreg))
        {
            wstring ws1 = wswhat[1];
            wstring ws2 = wswhat[2]; 
            string s1 = Wstring2String(ws1);
            string s2 = Wstring2String(ws2);
            fprintf(stdout, "%s\t%s\n", s1.c_str(), s2.c_str());
            wstrit=wswhat[0].second;  
        }
    }
    
    if (NULL != fin)
    {
        fclose(fin);
        fin = NULL;
    }
    return 0;
}
int main( int argc, char *argv[] )
{
    timeval tv1, tv2;
    gettimeofday(&tv1, NULL); 
    
    if ( 2 != argc )
    {
        PrintUsage();
        return 1;
    }
    
    LoadFile(argv[1]);
    gettimeofday(&tv2, NULL);
    fprintf(stderr,"%s has finished congratulations!\n",argv[0]);
    fprintf( stderr,"time elapsed: %.2f ms\n", (float)((tv2.tv_sec - tv1.tv_sec)


*1000000+(tv2.tv_usec-tv1.tv_usec))/1000);
    return 0;
}
========

你可能感兴趣的:(VC++,C++,boost)