您的位置:首页 > 编程语言 > C语言/C++

Boost之字符串

2016-07-04 16:35 429 查看

lexical_const

lexical_const库进行“字面值”的转换,类似C中的atoi函数,可以进行字符串与整数、浮点数之间的字面转换,使用时需要包含头文件<boost/lexical_cast.hpp>。
#include <iostream>
#include <string>
#include <boost/lexical_cast.hpp>
using namespace std;
using namespace boost;

int main()
{
/* 基本用法 */
int x = lexical_cast<int>("10");            //字符串->整数
string str = lexical_cast<string>(123);     //整数->字符串
string str2 = lexical_cast<string>(0x10);   //16进制整数->字符串
cout << x << ", " << str << ", " << str2 << endl;

/* 错误处理 */
try {
cout << lexical_cast<int>("0x10");      //要转换成数字的字符串中只能有数字和小数点
} catch (bad_lexical_cast &e) {
cout << "error: " << e.what() << endl;
}
if (!conversion::try_lexical_convert("0x10", x))     //判断是否能转换成功,避免抛出异常
cout << "不能将'0x10'转换成数字\n";
}
输出:
10, 123, 16

error: bad lexical cast: source type value could not be interpreted as target

不能将'0x10'转换成数字

string_ref

在C++中处理字符串的基本工具是标准字符串std::string,但构造一个std::string成本很高,因为它必须完全持有字符串的内容,极端的时候会有很高的内存拷贝代价是,影响程序效率。使用const std::string&可以避免一些问题,但它在处理C字符串、提取子串时却又无能为力。总而言之,std::string显得有些”重“,我们需要一种更”轻“的字符串工具。
boost.string_ref就是这样一种轻量极的字符串,它只持有字符串的引用,没有内存拷贝成本,所以运行效率很高,是更好的const std::string&。它的工作原理很简单,它不拷贝字符串,所以也就不分配内存,只用两个成员变量ptr_和len_标记字符串的起始位置和长度,这样就实现了字符串的表示。但需要注意的是,我们只能像const std::string&那样去观察字符串而无法修改字符串。使用时需要包含头文件<boost/utility/string_ref.hpp>。
#include <iostream>
#include <string>
#include <string.h>
#include <boost/utility/string_ref.hpp>
using names
4000
pace std;
using namespace boost;

int main()
{
const char *ch = "hello world";
string str(ch);         //标准字符串,有拷贝成本

string_ref s1(ch);      //字符数组构造,零拷贝
string_ref s2(str);     //标准字符串构造,零拷贝

/* 截取字符串 */
string_ref s3(ch, 4);
string str2 = str.substr(0, 4);

/* 赋值 */
string_ref s4, s5;
s4  = ch;
s5 = str;

/* 转换为标准字符串,获得一个拷贝 */
string str3 = s1.to_string();

/* 当做标准字符串使用(修改操作除外) */
if (s1.size() == strlen(ch))
cout << "s1.size() == strlen(ch)\n";

for(auto &x : s1)
{
cout << x ;
}
cout << endl;

if (s1.front() == 'H')
cout << "s1.front() == 'A'\n";

if (s1.find('o') == 4)
cout << "s1.find('o') == 4)\n";

auto substr = s1.substr(1, 4);
cout << "s1.substr(1, 4) = " << substr << endl;

/* 调整string_ref内部的字符串指针和长度,达到变动字符串引用的目的 */
s1.remove_prefix(2);                    //删除前两个字符
cout << "now: s1 = " << s1 << endl;
s1.remove_suffix(2);                    //删除后两个字符
cout << "now: s1 = " << s1 << endl;
}
输出:
s1.size() == strlen(ch)

hello world

s1.find('o') == 4)

s1.substr(1, 4) = ello

now: s1 = llo world

now: s1 = llo wor

string_algo

string_algo库是一个非常全面的字符串算法库,提供了大量的字符串操作函数,如大小写无关比较、修剪、特定模式的子串查找等。使用时需要包含头文件<boost/algorithm/string.hpp>。
string_algo库中的算法命名遵循了标准库的惯例,算法名均是小写形式,并使用不同的词缀来区分不同的版本,命名规则是:
前缀i :
大小写不敏感(忽略大小写),否则是大小写敏感的;
后缀_copy :
不变动输入,返回处理结果的拷贝,否则在原地址上处理。
后缀_if :
需要一个作为判断式的谓词函数对象,否则使用默认的判断准则。
#include <iostream>
#include <string>
#include <deque>
#include <list>
#include <boost/utility/string_ref.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/assign.hpp>
using namespace std;
using namespace boost;

int main()
{
/* 大小写转换 */
string str("HELLO world\n");
cout << to_upper_copy(str);     //返回大写后的拷贝
cout << str;                    //原字符串不改变
to_lower(str);                  //字符串小写
cout << str;                    //原字符串被改变
cout << endl;

/* 判断式 */
str = "hello wOrLd";

if (iends_with(str, "world"))                               //大小写无关检测后缀
cout << "iends_with(str, 'world'): true\n";
if (!ends_with(str, "world"))                               //大小写敏感检测后缀
cout << "ends_with(str, 'world'): false\n";
if (starts_with(str, "Pow"));                               //检测前缀
cout << "start_with(str, 'hello'): true\n";
if (contains(str, "ll"))                                    //测试包含关系
cout << "contains(str, 'll'): true\n";

string str2 = to_lower_copy(str);
if (iequals(str, str2))                                     //大小写无关判断相等
cout << "iequals(str, str2): true\n";

string str3("hello cpp");
if (ilexicographical_compare(str3, str))                    //大小写无关比较
cout << "ilexicographical_compare(str3, str): true\n";

if (all("hello", is_lower()))                               //检测字串均小写(all用来检测一个字符串中的所有元素是否满足指定的判断式)
cout << "all('hello', is_lower()): true\n";
cout << endl;

/* 分类和修剪 */
str = " hello boost ";
cout << trim_copy(str);         //删除两端的空格
cout << trim_left_copy(str);    //删除左端的空格

trim_right(str);                //删除右端的空格
cout << str;

str2 = "2016 Happy new Year!!!";
cout << trim_left_copy_if(str2, is_digit());                            //删除左端的数字
cout << trim_right_copy_if(str2, is_punct());                           //删除右端的标点
cout << trim_copy_if(str2, is_punct() || is_digit() || is_space());     //删除两端的标点、数字和空格

/* 查找 */
str = "Long long ago, there was a king.";

iterator_range<string::iterator> rge;                           //迭代器区间

rge = find_first(str, "long");                                  //找第一次出现
cout << "find_first: " << rge.begin() - str.begin() << endl;

rge = ifind_first(str, "long");                                 //大小写无关找第一次出现
cout << "ifind_first: " << rge.begin() - str.begin() << endl;

rge = find_nth(str, "ng", 2);                                   //找第三次出现
cout << "find_nth: " << rge.begin() - str.begin() << endl;

rge = find_head(str, 4);                                        //取前4个字符
cout << "find_head: " << rge << endl;

rge = find_tail(str, 5);                                        //取末尾5个字符
cout << "find_tail: " << rge << endl;

rge = find_first(str, "samus");
if (rge.empty() && !rge)                                        //找不到
cout << "find_first: " << "找不到\n\n";

/* 替换和删除 */
str = "Samus beat the monster.\n";

cout << replace_first_copy(str, "Samus", "samus");      //替换"Samus"在str中的第一次出现

replace_last(str, "beat", "kill");                      //替换"beat"在str中的最后一次出现
cout << str;

replace_tail(str, 9, "ridley.\n");                      //替换str的末尾9个字符
cout << str;

cout << ierase_all_copy(str, "samus");                  //删除"samus"在str中的所有出现
cout << replace_nth_copy(str, "l", 1, "L");             //替换"l"在str中的第1次出现
cout << erase_tail_copy(str, 8);                        //删除str的末尾8个字符
cout << endl << endl;

/* 分割
* 容器的元素类型必须是string或者iterator_range<string::iterator>
* 容器可以是vector、list、deque等标准容器
*/
str = "Samus,Link.Zelda::Mario-Luigi+zelda";

deque<string> d;
ifind_all(d, str, "zELDA");                             //大小无关分割字符串
for (auto x : d)
cout << "["<< x << "] ";
cout << endl;

list<iterator_range<string::iterator> > l;
split(l, str, is_any_of(",.:-+"));                      //使用标点分割
for (auto x : l)
cout << "["<< x << "]";
cout << endl;

l.clear();
split(l, str, is_any_of(".:-"), token_compress_on);     //token_compress_on表示当两个分隔符连续出现时将被视为一个
for (auto x : l)
cout << "["<< x << "]";
cout << endl << endl;

/* 合并 */
vector<string> v = assign::list_of("Samus")("Link")("Zelda")("Mario");
cout << join(v, "+") << endl;                           //简单合并

cout << join_if(v, "**",                                //带谓词的合并
[](string_ref s)                        //lambda表达式
{ return contains(s, "a"); }            //包含字符'a'
);
cout << endl << endl;

/* 查找(分割)迭代器 */
str = "Samus||samus||mario||||Link";

typedef find_iterator<string::iterator> string_find_iterator;

string_find_iterator pos, end;
for (pos = make_find_iterator(str, first_finder("samus", is_iequal())); pos != end; ++pos)
cout << "[" << *pos << "]";
cout << endl;

typedef split_iterator<string::iterator> string_split_iterator;

string_split_iterator p, endp;
for (p = make_split_iterator(str, first_finder("||", is_iequal())); p != endp; ++p)
cout << "[" << *p << "]";
cout << endl;
}
输出:
HELLO WORLD

HELLO world

hello world

iends_with(str, 'world'): true

ends_with(str, 'world'): false

start_with(str, 'hello'): true

contains(str, 'll'): true

iequals(str, str2): true

ilexicographical_compare(str3, str): true

all('hello', is_lower()): true

hello boosthello boost hello boost Happy new Year!!!2016 Happy new YearHappy ne

w Yearfind_first: 5

ifind_first: 0

find_nth: 29

find_head: Long

find_tail: king.

find_first: 找不到

samus beat the monster.

Samus kill the monster.

Samus kill the ridley.

kill the ridley.

Samus kilL the ridley.

Samus kill the

[Zelda] [zelda]

[Samus][Link][Zelda][][Mario][Luigi][zelda]

[Samus,Link][Zelda][Mario][Luigi+zelda]

Samus+Link+Zelda+Mario

Samus**Zelda**Mario

[Samus][samus]

[Samus][samus][mario][][Link]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ boost