rust str与string的 str 是不是 boost:string

随笔 - 686&
文章 - 8&评论 - 790&trackbacks - 19
c++在stl库中提供了一个string类用以代替c语言的char*来实现字符串功能,不过stl的string只提供了一个连接字符串和查找的功能,其它的常用函数几乎一律没有,就连字符串替换都得自己来实现,和c#的字符串函数比起来简直弱爆了。
boost库在头文件&boost/algorithm/string.hpp&中提供了不少字符串处理函数,用以帮助我们实现基本的字符串处理功能,极大程度上缓解了字符串函数不够用的问题。
&&&&string str1("hello abc-*-ABC-*-aBc goodbye");&&&&vector&string& SplitV // #2: Search for tokens&&&&split(SplitVec, str1, is_any_of("-*"), token_compress_on); // SplitVec == { "hello abc","ABC","aBc goodbye" }
上述代码就提供了一个split的功能,不过和c#的版本相比,还是不够简洁,如果设计成这样就更加好用了:
&&&&auto SplitVec = split(str1, is_any_of("-*"), token_compress_on);
之所以不以这种形式设计,貌似是因为如果在split函数里构造返回值的话,会有一次数据拷贝的开销。从中也可以看出,boost的设计还是以性能为主的。而.net程序天然没有返回值拷贝带来的开销,可以采取那种更简洁的接口形式。
PS:我觉得可以像.net那样,在堆变量中保存结果,然后通过auto_ptr封装后作作为返回值。即有简洁的接口形式,又没有数据拷贝的开销,堆变量也能通过auto_ptr自动释放。
同样,也是出于性能方向的考虑,对于会产生新字符串的函数,往往会有一个xxx和xxx_copy两个版本,例如tolower就有to_lower和to_lower_copy两个版本:一个是直接变更本身的值,一个是构造新字符串,具体选取那个根据实际场景来考虑。
另外,字符串比较函数中,往往有区分大小写和不区分大小写的算法。在boost中并不是通过参数来控制,而是直接提供xxx和ixxx两个版本,其中i就表示ignor case。如equals和iequals。还有的需要和条件函数一并使用的,这时就会提供一个xxx_if的版本。
由于提供的字符串函数比较多,这里我只按每类列举几个常用的函数和示例,如果同一个算法有xxx_copy的版本或ixxx版本,也只列举基本的形式。其它的情参看。
Case Conversion
大小写转换涉及到四个函数:、以及xxx_copy的版本。基本用法如下:
&&&&cout && to_upper_copy(string("hello world")) &&
Trimming函数主要有、、和他们的xxx_copy和xxx_if版本。用于去除字符串首位的空白字符:
&&&&cout && trim_copy(std::string("
hello world")) &&
当然,也不限于只去掉空白字符:
&&&&cout && trim_copy_if(std::string(",,,hello world"),
is_any_of(" ,.:")) &&
Predicates
Predicates函数主要有:&、&、&、&、&、以及他们的ixxx版本。基本上从名字里就可以看出怎么用了:
&&&&cout && (ends_with("hello world", "world") ? "true" : "false") &&
Find algorithms
查找算法有好几种:、、&、、、、。常见的用法如下:
&&&&auto result = find_first("hello world", "world");&&&&if(result.empty())&&&&&&&&cout && "can't find result" &&&&&&else&&&&&&&&cout && result &&
其中result是一个boost::iterator_range类型的对象,可以用它来构造子串。
&&&&string s("hello world");&&&&cout && s.substr(find_first(s, "wo").begin() - s.begin()) &&
或者来个更复杂点的:
&&&&string str1("abc-*-ABC-*-aBc");&&&&for(auto it = make_find_iterator(str1, first_finder("abc", is_iequal())); !it.eof(); ++it)&&&&{&&&&&&&&cout && copy_range&std::string&(*it) &&&&&&}
Erase/Replace
boost把erase和replace函数分开来列了,这样的好处是命名比较清晰,但不好的地方时函数变得非常多,不如重载的形式那么好记。
replace的函数有&、、&&以及它们的变体,加上erase,共有20多种,这里就不一一列举了。
&&&&cout && replace_all_copy(string("hello world"), "l", "-") &&
split函数的用法前面以及介绍过:
&&&&string str1("hello abc-*-ABC-*-aBc goodbye");&&&&vector&string& SplitV
&&&&split(SplitVec, str1, is_any_of("-*"), token_compress_on);
需要注意的是这里的token_compress_on参数,它可以吧连续多个分隔符当一个,默认没有打开,当用的时候一般是要打开的。
另外,boost把find_all函数也分到split一类里面去了,它们的用法到也确实类似。
&&&&string str1("hello abc-*-ABC-*-aBc goodbye");&&&&typedef
vector&iterator_range&string::iterator&& find_vector_type;&&&&find_vector_type FindV&&&&ifind_all( FindVec, str1, "abc" );
Join函数则是和split相反,用于把多个字符串拼接起来。
&&&&std::array&string, 3& k = {"hello", "world", "123"};&&&&cout && join(k, "-");&&&&&&&&//输出结果为: hello-world-123
它要求先把参数放到容器里,不像.net的那样可以直接传入动态参数那样好用,如果能写成这样的重载形式会更好点(当然,自己封一个也不难):
&&&&join("-", "hello", "world", "123", &)
其它还有一些条件函数,主要配合算法使用。如前面已经见过的、常用的还有、、、等,这里就不多介绍了。
阅读(...) 评论()Boost学习之格式化输出--format - 李sir - 博客园
boost::format类提供了类似C语言里'printf'功能的格式化输出能力,当然功能更强大。
所需头文件:
#include &boost/format.hpp&
#include&&iostream&
#include&&string&
#include&&boost/format.hpp&
using&namespace&
int&_tmain(int&argc,&_TCHAR*&argv[])
&&&&cout&&&&boost::format("writing&%1%,&&x=%2%&:&%3%-th&try")&%&"toto"&%&40.23&%&50&&&&
&&&&boost::format&fmter("%2%&%1%");
&&&&fmter&%&36;
&&&&fmter&%&77;
&&&&cout&&&&fmter&&&&
&&&&fmter&%&12;
&&&&fmter&%&24;
&&&&cout&&&&fmter&&&&
&&&&std::string&s&=&fmter.str();
&&&&std::string&s2&=&str(&boost::format("%2%&%1%&%2%&%1%")%"World"%"Hello");
&&&&cout&&&&s&&&&endl&&&&s2&&&&
&&&&cout&&&&boost::format("%3.1f&-&%.2f%%")&%&10.0&%&12.5&&&&&
&&&&cout&&&&boost::format("%2$3.1f&-&%1$.2f%%")&%&10.0&%&12.5&&&&&
&&&&cin.get();
&&&&return&0;
#include &iostream&
#include &string&
#include &boost/format.hpp&
int _tmain(int argc, _TCHAR* argv[])
// 使用%序号%的方式给出指示符, 后面用%连接对应的数据。
cout && boost::format("writing %1%,
x=%2% : %3%-th try") % "toto" % 40.23 % 50 &&
// 输出:writing toto,
x=40.23 : 50-th try
// 可以延迟使用,顺序不必一致
boost::format fmter("%2% %1%");
fmter % 36;
fmter % 77;
cout && fmter &&
// 输出:77 36
fmter % 12;
fmter % 24;
cout && fmter &&
// 输出:24 12
// 可直接转成字符串
std::string s = fmter.str();
std::string s2 = str( boost::format("%2% %1% %2% %1%")%"World"%"Hello");
cout && s && endl && s2 &&
// Hello World Hello World
// 可以使用printf指示符
cout && boost::format("%3.1f - %.2f%%") % 10.0 % 12.5
// 输出:10.0 - 12.50%
// printf指示符里使用N$指定使用第几个参数
cout && boost::format("%2$3.1f - %1$.2f%%") % 10.0 % 12.5
// 输出:12.5 - 10.00%
cin.get();
boost::format里的指示符语法大致有三大类:
继承并强化自printf的格式化字符串
&&& 形式为:[ N$ ] [ flags ] [ width ] [ . precision ] type-char&&& N$可选,指定使用第N个参数(注意,要么所有指示符都加此参数,要么都不加)&&& 接下来的参数可以参数printf的指示符,只是format为其中的flags添加了'_'和'='标志,用于指出内部对齐和居中对齐。
设置打印规则,它是printf参数的一个补充,只是为了更直观点。
&&& 形式为:%|spec|&&& 如:%|1$+5|表示显示第一个参数,显示正负号,宽度为5
简单的位置标记
&&& 形式为:%N%&&& 简单地声明显示第N个参数,优点是比较直观而且不用指定类型。4838人阅读
[C++]--[Boost](49)
C++98在标准库中提供了字符串标准类std::string. 它有一些成员函数可以查找子串, 访问字符, 可以执行基本的字符串处理功能. 由于std::string符合容器的定义, 也可以把它看做是元素类型为char(或wchar t)的序列容器, 可以使用标准算法来对它进行运算, 但标准算法并不是为字符串处理定制的, 很多时候会显得有些&笨拙&.
string_algo库的出现改变了这个尴尬的局面. 它是一个非常全面的字符串算法库, 提
了大量的字符串操作函数, 如大小写无关比较、修剪、特定模式的子串查找等.
string_algo库位于名字空间boost::algorithm, 为了使用string_algo组件, 需要包含头文件&boost/algorithm/string.hpp&。string_algo同样也是一组类的总称,相当于一个sub library了。其位置在boost/algorithm/string目录下,包含的主要内容如下:
case_conv.hpp:& 大小写转换,包含 to_lower_copy, to_lower, to_upper_copy, to_upper
classification.hpp: 字符类别,包含 is_classified(std::ctype_base::mask, locale), is_space, is_alnum, is_upper, is_xdigit等方法
cllection_traits.hpp: 一大堆traits类,用于统一char的各种集合类,比如 STL collections, c-style array, null-terminated c-strings等的编程接口。
compare.hpp: 字符串字符的functor,提供了is_equal, is_iequal两个predicates.
concept.hpp: concept定义,包含FinderConcept和FormatterConcept
constants.hpp: 定义了一个enum token_compress_mode_type
erase.hpp: 提供了一组从string中移除字符和子串的方法,什么样的都有。
find.hpp: 提供了一组从string中寻找子串的方法,允许指定各种寻找子串的条作。
finder.hpp:& 定义了一组生成string finder的方法
formatter.hpp: 定义了一组生成string formatter的方法
predicate.hpp: 提供了一组predictate, 包含starts_with, ends_withs, contains等
replace.hpp: 提供了一组从string中替换子串的方法
split:hpp: 提供了一组分割子串的方法。
trim.hpp: trim算法。
2. 命名规则
string_algo库中的算法命名遵循了标准库的惯例, 算法名均为小写形式, 并使用不同的前缀或者后缀来区分不同的版本, 如下:
前缀i: 有这个前缀表明算法是大小写不敏感的,否则是大小写敏感的:
后缀copy: 有这个后缀表明算法不变动输入, 返回处理结果的拷贝, 否则算法原地处理, 输入即输出.
后缀if: 有这个后缀表明算法需要一个作为判断式的谓词函数对象,否则使用默认的判断准则.
3. 算法分类
string_algo库提供的算法共分五大类,如下:
1. 大小写转换
2. 判断式与分类
4. 查找与替换
5. 分割与合井
4. 例: 3.1-3.3
void test_string_case()
// 返回大写拷贝, 原字符串改变
std::string str1(&I Don't Know. &);
boost::to_upper(str1);
std::cout && &str1 = & && str1 && std::
// 返回大写拷贝, 原字符串不改变
std::string str2(&I Don't Know. &);
std::string str3 = boost::to_upper_copy(str2);
std::cout && &str2 = & && str2 && std::
std::cout && &str3 = & && str3 && std::
void test_string_trim()
std::string str1 = &
std::string str2 = boost::trim_left_copy(str1);
std::string str3 = boost::trim_right_copy(str1);
std::string str4 = boost::trim_copy(str1);
assert(str2==&abc
assert(str3==&
assert(str4==&abc&);
std::string str5 = &8&;
std::string str6 = boost::trim_left_copy_if(str5, boost::is_any_of(&0&));
std::cout && str6 && std::
void test_string_precidate()
// starts_with
assert(boost::starts_with(&boost_python-vc100-mt-1_49.dll&, &boost&));
assert(!boost::starts_with(&boost_python-vc100-mt-1_49.dll&, &BOOST&));
assert(boost::istarts_with(&boost_python-vc71-mt-1_33.dll&, &BOOST&));
// ends_with
assert(boost::ends_with(&boost_python-vc100-mt-1_49.dll&, &.dll&));
assert(!boost::ends_with(&boost_python-vc100-mt-1_49.dll&, &.DLL&));
assert(boost::iends_with(&boost_python-vc100-mt-1_49.dll&, &.DLL&));
// contains
assert(boost::contains(&boost_python-vc100-mt-1_49.dll&, &python&));
assert(!boost::contains(&boost_python-vc100-mt-1_49.dll&, &PYTHON&));
assert(boost::icontains(&boost_python-vc100-mt-1_49.dll&, &PYTHON&));
assert(boost::equals(&boost&, &boost&));
assert(!boost::equals(&boost&, &BOOST&));
assert(boost::iequals(&boost&, &BOOST&));
// Empty string test
assert(boost::starts_with(&boost_python-vc100-mt-1_49.dll&, &&));
assert(boost::ends_with(&boost_python-vc100-mt-1_49.dll&, &&));
assert(boost::contains(&boost_python-vc100-mt-1_49.dll&, &&));
// lexicalgrephical_compare
assert(boost::lexicographical_compare(&boost_python-vc100-mt-1_49.dll&, &boost_system-vc100-mt-1_49.dll&));
// all: 如果它的所有元素满足一个给定的通过判断式描述的条件,则这个条件式成立。
assert(boost::all(&\x20\t\n\r&, boost::is_space()));
assert(boost::all(&\x20\t\n\r&, boost::is_classified(std::ctype_base::space)));
assert(boost::all(&\x20\t\n\r&, boost::is_any_of(&\x20\t\n\r&)));
assert(boost::all(&abcde&, boost::is_from_range('a','e')));
assert(boost::all(&abcde&, boost::is_from_range('a','z')));
assert(!boost::all(&abcde&, boost::is_from_range('b','c')));
assert(boost::all(&abc __ de&, boost::is_from_range('a','z') || boost::is_space() || boost::is_any_of(&_&)));
void test_string_classify()
is_space: 字符是否为空格
is_alnum: 字符是否为字母和数字字符
is_alpha: 字符是否为字母
is_cntrl: 字符是否为控制字符
is_digit: 字符是否为十进制数字
is_graph: 字符是否为图形字符
is_lower: 字符是否为小写字符
is_print: 字符是否为可打印字符
is_punct: 字符是否为标点符号字符
is_upper: 字符是否为大写字符
is_xdigit: 字符是否为十六进制数字
is_any_of: 字符是否是参数字符序列中的任意字符
if_from_range 字符是否位于指定区间内,即from &= ch &= to
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1776153次
积分:20319
积分:20319
排名:第233名
原创:347篇
转载:183篇
评论:213条
(4)(16)(4)(5)(5)(1)(6)(4)(14)(19)(25)(40)(44)(14)(33)(18)(4)(25)(17)(15)(37)(16)(4)(21)(20)(8)(2)(2)(19)(16)(15)(19)(2)(8)(5)(1)(4)(1)(5)(6)(5)(1)2670人阅读
BOOST(2)
Boost::String
#include &boost/algorithm/string.hpp&
1. Header &boost/algorithm/string/case_conv.hpp&
boost::to_upper(str1); //直接改变str1的值
boost::to_lower(str1);
string str2 = boost::to_lower_copy(str1); & //不改变str1的值,返回副本
string str2 = boost::to_upper_copy(str1); & //不改变str1的值,返回副本
2. Header &boost/algorithm/string/classification.hpp&
Boost.StringAlgorithms 库提供了几个从字符串中删除单独字母的函数,&
可以明确指定在哪里删除,如何删除。
例如,可以使用函数 boost::algorithm::erase_all_copy() 从整个字符串中 删除特定的某个字符。&
如果只在此字符首次出现时删除,可以使用函数 boost::algorithm::erase_first_copy() 。&
如果要在字符串头部或尾部删除若干字符,可以使用函数 boost::algorithm::erase_head_copy() 和 boost::algorithm::erase_tail_copy() 。
3. Header &boost/algorithm/string/trim.hpp&
boost::algorithm::trim_copy_if(str1, boost::algorithm::is_digit()) &//删除首位所有的数字
trim_left_copy
trim_left_copy_if
trim_right_copy
trim_right_copy_if
#trim_if#&
inline void trim_if(SequenceT& Input, PredicateT IsSpace)
可自定义谓词 &predicate&
//删除'空格' 和 '0-5'
bool foo2(const char& h)
& & bool ret =
& & if(h==' ' || (h&='0' && h&='5'))
& & & & ret =
cout && boost::algorithm::trim_left_copy_if(str1, foo2) &&
4. Header &boost/algorithm/string/classification.hpp&
is_classified(std::ctype_base::mask Type, const std::locale& Loc=std::locale())
is_space(const std::locale& Loc=std::locale())
is_alnum(const std::locale& Loc=std::locale())
is_alpha(const std::locale& Loc=std::locale())
is_cntrl(const std::locale& Loc=std::locale())
is_digit(const std::locale& Loc=std::locale())
is_graph(const std::locale& Loc=std::locale())
is_lower(const std::locale& Loc=std::locale())
is_print(const std::locale& Loc=std::locale())
is_punct(const std::locale& Loc=std::locale())
is_upper(const std::locale& Loc=std::locale())
is_xdigit(const std::locale& Loc=std::locale())
is_any_of( const RangeT& Set )
inline detail::is_from_rangeF&CharT& is_from_range(CharT From, CharT To)
5. Header &boost/algorithm/string/compare.hpp&
namespace boost { &
namespace algorithm {
& & struct is_
& & struct is_ & &
& & struct is_ & &
& & struct is_
& & struct is_not_ & &
& & struct is_not_ &
bool operator()(const T1 &, const T2 &)
6. Header &boost/algorithm/string/erase.hpp&
OutputIterator erase_range_copy (OutputIterator, Input, SearchRange);
Sequence erase_range_copy (Input, SearchRange);&
void erase_range (Input, SearchRange);
删除输入字符串中SearchRange那部分。SearchRange是一个iterator_range对象。
iterator_range( Iterator Begin, Iterator End )
//删除s[0]-s[4]的字串
cout && boost::algorithm::erase_range_copy(str1, boost::make_iterator_range(str1.begin(), str1.begin()+5)) &&
boost::algorithm::trim_copy_if(str1, boost::algorithm::is_from_range('1', '5'));//删除'1'-'5'的字串
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:208449次
积分:2547
积分:2547
排名:第9234名
原创:27篇
转载:111篇
评论:29条
(1)(1)(1)(3)(1)(1)(1)(2)(1)(3)(2)(2)(1)(1)(2)(2)(2)(1)(1)(1)(2)(2)(1)(1)(5)(1)(1)(1)(1)(5)(7)(14)(9)(6)(5)(6)(2)(3)(6)(4)(3)(5)(2)(19)

我要回帖

更多关于 rust 蓝图兑换的原则 的文章

 

随机推荐