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 <string>
#include <sstream>
#include <vector>
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<sms_info>& smss); static bool parse(const std::string& s, std::vector<sms_info>& 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 <boost/progress.hpp>
#include "sstream"
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/foreach.hpp>
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<sms_info> 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<sms_info> smss2; parse(s, smss2); assert(smss1.size() == smss2.size());
}
std::string json_parser::generate(const std::vector<sms_info>& 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<sms_info>& 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<int>(sms_info::INDEX); std::string to = p.get<std::string>(sms_info::TO); std::string from = p.get<std::string>(sms_info::FROM); std::string msg = p.get<std::string>(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<int, pair<char, float> > (3, make_pair<char, float> ('a', 0.9));
随着您添加更多的元素,创建元组结构将变得越来越困难。Boost tuple 类型派上了用场。要使用
boost::tuple,必须包括头文件 tuple.hpp。要执行元组比较和组 I/O,您需要分别包括
tuple_comparison.hpp 和tuple_io.hpp。
第一个使用元组的程序
清单 1 使用 int、char 和 float 的元组并打印内容。
清单 1. 创建 Boost 元组并打印内容
#include <iostream>
#include <tuple.hpp>
#include <tuple_comparison.hpp>
#include <tuple_io.hpp>
using namespace boost;
int main ( )
{tuple<int, char, float> 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 <tuple.hpp>
#include <tuple_comparison.hpp>
#include <tuple_io.hpp>
#include <iostream>
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<int, X> t(3, X(2));return 0;
}
与 STL 提供的 make_pair 函数非常类似,Boost 提供了 make_tuple 例程。要从函数返回元组,您必
须调用make_tuple。可以创建具有临时元素的元组;清单 3 的输出为 (4 0)。
清单 3.使用 make_tuple 来从函数返回元组
#include <tuple.hpp>
#include <tuple_comparison.hpp>
#include <tuple_io.hpp>
#include <iostream>
using namespace std;
boost::tuple<int, int>
divide_and_modulo(int a, int b)
{return boost::make_tuple<int, int> (a/b, a%b);
}int main ( )
{boost::tuple<int, int> t = divide_and_modulo(8, 2);cout << t << endl;return 0;
}
要访问元组的各个元素,您可以使用 get 例程。此例程具有两种变体,如清单 4 所示。请注意,还可
以使用 get 例程来设置元组的各个元素,虽然有些编译器可能不支持此功能。
清单 4. 使用 boost::get 例程
#include <tuple.hpp>
#include <tuple_comparison.hpp>
#include <tuple_io.hpp>
#include <iostream>
using namespace std;
boost::tuple<int, int>
divide_and_modulo(int a, int b)
{return boost::make_tuple<int, int> (a/b, a%b);
}int main ( )
{boost::tuple<int, int> t = divide_and_modulo(8, 2);cout << t.get<0> () << endl; // prints 4cout << boost::get<1>(t) << endl; // prints 0boost::get<0>(t) = 9; // resets element 0 of t to 9++boost::get<0>(t); // increments element 0 of tcout << t.get<1>() << endl; // prints 10return 0;
}
可以使用 const 限定符来声明元组,在这种情况下,用于访问特定元素的 get 调用将返回对 const 的
引用。不能对以这种方式访问的元素进行赋值(请参见清单 5)。
清单 5. 使用 const 限定符来声明的元组不可修改
#include <tuple.hpp>
#include <tuple_comparison.hpp>
#include <tuple_io.hpp>
#include <iostream>
using namespace std;
int main ( )
{const boost::tuple<int, char*> t(8, "Hello World!");t.get<1> ()[0] = "Y"; // error!boost::get<0>(t) = 9; // error!return 0;
}
可以使用关系运算符 ==、!=、<、>、<= 和 >= 对相同长度的元组进行比较。比较不同长度的元组会产
生编译时错误。这些运算符的工作原理是从左到右地比较两个参与元组的每个单独的元素(请参见清单
6)。
清单 6. 关系运算符与元组
#include <tuple.hpp>
#include <tuple_comparison.hpp>
#include <tuple_io.hpp>
#include <iostream>
#include <string>
using namespace std;
int main ( )
{boost::tuple<int, string> t(8, string ("Hello World!"));boost::tuple<int, string> t2(8, string("Hello World!"));cout << (t == t2) << endl;boost::tuple<int, string> r(9, string ("Hello World!"));boost::tuple<int, string> r2(8, string("Hello World!"));cout << (r > r2) << endl;boost::tuple<string, string> q(string ("AA"), string("BB"));boost::tuple<string, string> q2(string("AA"), string ("CC"));cout << (q < q2) << endl;return 0;
}
清单 6 的输出为 1 1 1。请注意,如果您不是使用 string 或 int,而是使用没有定义 ==、!= 等运算
符的用户定义的随机类,则会产生编译错误。
2.Boost 静态断言
断言是 C/C++ 中的防错性程序设计的一部分。最常见的用法如下:
assert(<some expression you expect to be true at this point in code>);
assert 例程仅在调试模式下有效。在发布模式下,通常使用预处理器宏 ¨CDNDEBUG 来编译代码,其效
果相当于assert 不存在。静态断言建立在这个基本概念之上,只不过静态断言仅在编译时有效。此外,
静态断言不生成任何代码。
例如,假设您在一个整型变量中执行某个位操作,并预期其大小为 4:这并非在所有操作系统平台上都
是如此(请参见清单 7)。
清单 7. 使用 Boost 静态断言来验证变量的大小
#include <boost/static_assert.hpp>
int main ( )
{BOOST_STATIC_ASSERT(sizeof(int) == 4);// … other code goes herereturn 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 <iostream>
#include <static_assert.hpp>
using namespace std;
using namespace boost;template<class T>
class A
{private:T x, y;BOOST_STATIC_ASSERT(numeric_limits<T>::is_signed);public:A(T x1, T y1) : x(x1), y(y1) { }
};int main ( )
{A<unsigned long> a(2, 1);return 0;
}
在清单 8 中,仅当 T 有符号时,模板类 A 才能进行实例化。类 numeric_limits 是标准命名空间的一
部分;它检查基本类型在给定操作系统平台上的属性。在无符号(unsigned )的 long 类型的情况下,
专用变体numeric_limits<unsigned int> 的 is_signed 标志为 false。当您在类范围中使用
BOOST_STATIC_ASSERT时,它是私有的、受保护的还是公开的并不重要。
清单 9 将 BOOST_STATIC_ASSERT 与函数结合在一起使用。该代码确保在函数 f1 中处理的类型只能是
A 类型或其派生类型。通过使用 Boost 的静态断言宏和 is_convertible 例程(在
boost/type_traits/is_convertible.hpp 中定义),此代码确保不希望的类型不会最终调用此例程。
清单 9. 将函数限制为仅处理特定的数据类型
#include <iostream>
#include <static_assert.hpp>
#include <boost/type_traits/is_convertible.hpp>
using namespace std;
using namespace boost;
struct A
{int a;float b;
};
struct B : public A{
};
template <typename T>
int f1 (T y)
{BOOST_STATIC_ASSERT ((is_convertible<T, A*>::value));return 0;
}int main ( )
{f1<B*> (new B);return 0;
}
3.使用 Boost 库生成随机数
随机数生成用于各种各样的计算机应用,例如安全和游戏。UNIX 系统一般附带了随机数生成例程 rand
和 srand。通常,srand 使用新的种子值来初始化 rand(请参见清单 10)。
清单 10. 用于在传统 UNIX 中生成随机数的代码
#include <stdlib.h>
#include <stdio.h>
int main ( )
{srand(time(NULL)); // this introduces randomnessfor (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 <iostream>
#include <boost/random.hpp>
using namespace std;
using namespace boost;
int main ( )
{uniform_int<> distribution (1, 100) ;mt19937 engine ;variate_generator<mt19937, uniform_int<> > 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 <iostream>
#include <boost/random.hpp>
using namespace std;
using namespace boost;
int main ( )
{uniform_real<> distribution(1, 2) ;kreutzer1986 engine ;variate_generator<kreutzer1986, uniform_real<> > 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 <iostream>
#include <boost/pool/pool.hpp>
#include <boost/pool/object_pool.hpp>
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<A> q;for (int i=0; i<10; ++i)A* a = q.construct(); // Calls A's constructor 10 timesreturn 0;
}
singleton_pool 接口——与 pool 接口几乎相同,但是用作独立池。独立池的底层结构具有为 malloc
、free 等声明的静态成员函数,并且构造函数是私有的。独立池声明中的第一个参数称为标记— —它
允许存在不同的独立池集(例如,用于 int 的多个池,其中每个池服务于不同的目的)。必须包括
singleton_pool.hpp 头文件才能使用此接口。请参见清单 14。
清单 14. singleton_pool 接口
#include <iostream>
#include <boost/pool/singleton_pool.hpp>
using namespace std;
using namespace boost;
struct intpool { };
struct intpool2 { };
typedef boost::singleton_pool<intpool, sizeof(int)> ipool1;
typedef boost::singleton_pool<intpool2, sizeof(int)> 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
<boost/pool/pool_alloc.hpp>
std::vector<int, boost::pool_allocator<int> > v;
std::list<double, boost::fast_pool_allocator<double> > 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 <string>
#include <iostream>
#include <boost/program_options.hpp>
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<string> (),"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<string>() << ".n";
} else {
cout << "No file specifiedn";
}
…
请注意,variable_map 类在许多方面与哈希表非常相似。例如,要检索 file 参数,您可以调用 vmap
["file"]。
提供多个参数和缩写的命令选项
命令行处理通常同时需要同一个命令选项的短名称和长名称。此外,您通常必须多次使用某个选项,以
便收集该选项的所有参数。例如,您可能希望使用 ¨Ch 和 ¨Chelp 来打印可用的命令。清单 16 演示
了这些功能。
清单 16. 使用较短的选项变体并允许多次调用命令选项
#include <string>
#include <iostream>
#include <boost/program_options.hpp>
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<vector<string> >( ),"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<string> ifiles(vmap["file"].as< vector<string> > ());vector<string>::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<string>中。下面是使用不同的参数来多次指定 ¨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=<first parameter>,第二个参数转换为 --do-
file=<second parameter>。
清单 17. 将位置参数与命令行选项相关联
#include <string>
#include <iostream>
#include <boost/program_options.hpp>
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<string>(),
"Provide input file name")
("do-file", boost::program_options::value<string>(),
"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<string> ( ) << endl;
}
if (vmap.count("do-file")) {
cout << "do- file: " << vmap["do-file"].as<string> ( ) << 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<int> 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<int> 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 <cstdlib>
#include <iostream>
#include <string>
#include <boost/progress.hpp>
#include <boost/asio.hpp>
#include <fstream>
#include <vector>
using namespace std;
using namespace boost;
void test001() {
std::vector<std::string> v(100);
std::ofstream fs;
progress_display pd(v.size());
std::vector<string>::iterator it;
for (it = v.begin(); it != v.end(); ++it) {
fs << *it << std::endl;
++it;
cout << "*";
//sleep(1);
}
cout << endl;
}
#include <boost/date_time/gregorian/greg_date.hpp>
#include <boost/date_time/gregorian_calendar.hpp>
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 <boost/shared_ptr.hpp>
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<Shared> SharedSP;
typedef std::vector<SharedSP> VShared;
VShared v;
v.push_back(SharedSP(new Shared()));
v.push_back(SharedSP(new Shared()));
}
#include <boost/lexical_cast.hpp>
//字符串转换为整形
void test004(string str) {
int i = boost::lexical_cast<int>(str);
cout << i << endl;
}
#include <boost/format.hpp>
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 <boost/algorithm/string.hpp>
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<char> v(str.begin(), str.end());
vector<char> v2 = to_upper_copy(erase_first_copy(v, "txt"));
for (int i = 0; i < v2.size(); ++i) {
cout << v2[i];
}
cout << endl;
}
#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 << "-";
}
cout << endl;
}
#include <boost/xpressive/xpressive_dynamic.hpp>
#include <boost/regex.hpp>
//需要编译器加上 -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 <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() << "=";
try {
int result = any_cast<int>(a[i]);
cout << result << endl;
} catch (boost::bad_any_cast & ex) {
cout << "cast error:" << ex.what() << endl;
}
}
}
#include <boost/thread/thread.hpp>
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<<str<<endl;*/
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<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <sys/time.h>
#include<ctype.h>
#include<locale.h>
#include "boost/regex.hpp"
#include <iconv.h>
#include <errno.h>
#include<algorithm>
// please add your code here!
using namespace std;
#define MAX_LINE_LENGTH 1048576
#define TAGLEN 50
/************************************************************
* @brief <funcName:trim> 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 <funcName:> 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 <funcName:> 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 <funcName:> 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 <funcName:PrintUsage> 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<string> 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<string>::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;
}
========
C++ boost 实例学习相关推荐
- 【多实例学习】2017-PR-多实例学习:问题特征和应用的调查
2017-PR-Multiple instance learning: A survey of problem characteristics and applications 多实例学习:问题特征和 ...
- Linux下安装 boost 库
1. 先去官网下载压缩包: https://www.boost.org/ 2. 解压后cd 进入根目录,然后执行: ./bootstrap.sh 3. 安装(时间会很长): ./b2 install ...
- Mysql依赖库Boost的源码安装,linux下boost库的安装
boost'准标准库'安装过程. 安装的是boost_1_60_0. (1)首先去下载最新的boost代码包,网址www.boost.org. (2)进入到自己的目录,解压: bzip2 -d boo ...
- 函数指针amp;绑定: boost::functoin/std::function/bind
see link: https://isocpp.org/wiki/faq/pointers-to-members function vs template: http://stackoverflow ...
- Boost 1.53.0 发布,可移植的C++标准库
Boost 1.53.0 发布了,包含了 5 个新的库,修复了一些安全漏洞以及 Boost.Locale 组件的 bug . 新增的 5 个库包括: Boost.Atomic Boost.Corout ...
- cmake开发环境 linux qt_一步步搭建CMake+QT+VTK+BOOST开发环境
开发环境: 1.可以迅速处理大量并发网络数据包,ASIO库和winpcap 4.1.3库; 2.处理与显示点云模型数据,使用VTK 8.2.0库; 3.项目使用CMake+VC2017编译,GUI使用 ...
- boost::asio使用UDP协议通信源码实现
说明:以下源码来自参考文献[1], 比原文更丰富, 更有指导意义, 方便日后参考. udp servr端源码 //g++ -g udp_server.cpp -o udp_server -lboost ...
- 使用boost解析域名服务
下面的源码给出了使用boost::asio进行域名解析的方法. //g++ -g resolver_demo.cpp -o resolver_demo -lboost_system -lpthread ...
- boost::asio异步模式的C/S客户端源码实现
异步模式的服务器源码 //g++ -g async_tcp_server.cpp -o async_tcp_server -lboost_system //#include <iostream& ...
最新文章
- TCP协议的服务器与客户端的程序设计(代码注释超详细)
- ISME:多组学揭示低氧环境下的汞甲基化细菌
- 02day-webpack
- Java 获取键盘输入
- 如何让你的百万级SQL运行得更快 else
- C#中使用JavaScriptSerializer类实现序列化与反序列化
- redhat enterprise linux 哪个版本好,Red Hat Enterprise Linux 版本显示中(Santiago)是啥意思?...
- 苹果手机免密支付怎么取消_超市“扫码枪”有啥神奇功能?直接扫走你的资金,不用输入密码|移动支付|手机|免密...
- php数组连起来,PHP 数组的拼接重组
- 为什么tcp不采用停等协议_为什么 TCP 协议有粘包问题
- 贪心 FZU 2013 A short problem
- oracle 命令行执行sql文件
- SQL Server 中的嵌套事务与@@TranCount(转)
- 【差分算法入门】例题讲解(代码逐句分析)
- JavaScript自学笔记 第5次
- 三菱 MX COMPONENT下载及安装测试
- HeadFirstJava——13_网络与线程
- 诺基亚3230用PC套件备份联系人却不能恢复的解决办法
- xampp 可道云_利用xampp+可道云KodExplorer本地搭建私有云
- ewebeditor编辑器漏洞连接大马复现
热门文章
- v-if 和 v-else-if 和 v-else 的使用
- SpringBoot与Shiro整合-概述
- Selector选择器概述||Selector选择器组合使用
- Docker selenium自动化 - 执行程序没反应、不执行原因,强制处理之前失败的进程,“... requests waiting for a slot to be free“问题解决
- Python 技术篇-使用opencv库读取中文路径图片报错解决办法
- Pytorch自定义数据集
- 用TensorFlow训练第一个模型
- SURF角点检测(python)
- web页面到ajax,页面使用ajax加载页面后如果运行其中的js,webpack如何多页面展示...
- 设计模式---设计模式的分类及六大原则