log4cpp源码阅读:StringUtil工具类
发布日期:2022-03-16 03:25:41 浏览次数:18 分类:技术文章

本文共 3542 字,大约阅读时间需要 11 分钟。

StringUtil

位置

  • src/StringUtil.cpp
  • src/StringUtil.hh

功能

  • 这是一个工具类,这个类提供了std::string对象的三个方法,其中trim方法和split方法,是std::string类他自身本来所没有提供的。 还有一个是将格式化字符串和具体的可变参数转为实际的字符串
class StringUtil {
public: static std::string vform(const char* format, va_list args); static std::string trim(const std::string& s); static unsigned int split(std::vector
& v, const std::string& s, char delimiter, unsigned int maxSegments = INT_MAX); template
static unsigned int split(T& output, const std::string& s, char delimiter, unsigned int maxSegments = INT_MAX) ; };

实现

  1. 首先看一下StringUtil::vform方法的实现
// 将格式化字符串format和可变参数args转换为具体的字符串类型 std::string StringUtil::vform(const char* format, va_list args) {
size_t size = 1024; char* buffer = new char[size]; while (1) {
va_list args_copy; va_copy(args_copy, args); int n = vsnprintf(buffer, size, format, args_copy); va_end(args_copy); if ((n > -1) && (static_cast
(n) < size)) {
std::string s(buffer); delete [] buffer; return s; } // 可能是空间小了,那么分配多一点空间再次尝试 size = (n > -1) ? n + 1 : size * 2; delete [] buffer; buffer = new char[size]; } }

vsprintf_s函数需要缓冲区来接收格式化后的结果,因为不知道具体有多少参数,导致最后格式化后的字符串长度是不同的,这里的解决方法是进行尝试,当失败的时候,就选择更大的缓冲区来进行接收

  1. StringUtil.trim实现
std::string StringUtil::trim(const std::string& s) {
static const char* whiteSpace = " \t\r\n"; // test for null string if(s.empty()) return s; // 找左边第一个不在whiteSpaces列表中的字符 std::string::size_type b = s.find_first_not_of(whiteSpace); if(b == std::string::npos) // No non-spaces return ""; // 然后从最后向前查找,第一个不在whiteSpaces中的字符 std::string::size_type e = s.find_last_not_of(whiteSpace); // 返回剩下的字符 return std::string(s, b, e - b + 1); }

可以看出这个方法可以取出首尾两端的空白字符(包括回车、制表符,换行符)

  1. StringUtil.split实现
unsigned int StringUtil::split(std::vector
& v, const std::string& s, char delimiter, unsigned int maxSegments) {
v.clear(); std::back_insert_iterator
> it(v); //创建后插迭代器适配器利用下面建好的模板方法 return split(it, s, delimiter, maxSegments); //调用下面的方法模板 }template
static unsigned int split(T& output, const std::string& s, char delimiter, unsigned int maxSegments = INT_MAX) {
std::string::size_type left = 0; //找到第一个有效的字符 unsigned int i; for(i = 1; i < maxSegments; i++) {
std::string::size_type right = s.find(delimiter, left); //当前 delimeter所有的位置 if (right == std::string::npos) {
break; } *output++ = s.substr(left, right - left); left = right + 1; } *output++ = s.substr(left); return i; }

主要实现思路,是记录两个位置,一个位置是第一个有效的字符,,程序中是left变量,另一个位置是当前 delimeter所有的位置,程序中是right变量,然后将[left, right)之间的字符拷贝到output中,然后移动 left, right到下一个位置(符合上述规则的位置),要小心最后一次找不到delimeter的情况。

上面的实现思路其实解决不了连续出现两个都是delimeter字符的情况。比如"1,2,3“这种情况,最后的结果 中必然存在一个空字符,还解决不了当最后一个字符是delimeter的情况,因为这个方法,最后没有进行检测,那么 假如输入是"1,2,3,4,",那么最后也必然会有一个空字符

转载地址:https://blog.csdn.net/zhizhengguan/article/details/123138559 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:log4cpp源码阅读:TimeStamp工具类
下一篇:log4cpp源码阅读:threading工具类

发表评论

最新留言

做的很好,不错不错
[***.243.131.199]2024年04月25日 13时28分59秒