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++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- boost相关小知识(长期顶置更新)
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C++的template模板中class与typename关键字的区别分析