log4cpp源码阅读:StringUtil工具类

1059 篇文章 280 订阅

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<std::string>& v, 
				  const std::string& s, char delimiter,
				  unsigned int maxSegments = INT_MAX);
				  
        template<typename T> 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<size_t>(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<std::string>& v,
                                const std::string& s,
                                char delimiter, 
                                unsigned int maxSegments) {
        v.clear();
        std::back_insert_iterator<std::vector<std::string> > it(v);  //创建后插迭代器适配器利用下面建好的模板方法
        return split(it, s, delimiter, maxSegments);  //调用下面的方法模板
    }


template<typename T> 
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,",那么最后也必然会有一个空字符

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
/app/smsprev4/src/NewCore/piliang_src_cluster_2023/plcb_2/src/util.cpp:683: undefined reference to `GetHistParam(inpackage*, std::string&, std::string&, std::string&, std::string&, std::string&, std::string&, int&, std::string&, oracle::occi::Date&, int&, std::string&, oracle::occi::Date&, oracle::occi::Date&, oracle::occi::Date&, std::string&, std::string&, std::string&, std::string&, std::string&, std::string)' /app/smsprev4/src/NewCore/piliang_src_cluster_2023/plcb_2/src/util.cpp:714: undefined reference to `updatePreCB(inpackage*, oracle::occi::Date, std::string, std::string, std::string&)' /app/smsprev4/src/NewCore/piliang_src_cluster_2023/plcb_2/src/util.cpp:808: undefined reference to `updatePreCB(inpackage*, oracle::occi::Date, std::string, std::string, std::string&)' bin/util.o: In function `process_xhx_file(std::string, std::string, std::string, int, CFileControl*)': /app/smsprev4/src/NewCore/piliang_src_cluster_2023/plcb_2/src/util.cpp:987: undefined reference to `GetHistParam(inpackage*, std::string&, std::string&, std::string&, std::string&, std::string&, std::string&, int&, std::string&, oracle::occi::Date&, int&, std::string&, oracle::occi::Date&, oracle::occi::Date&, oracle::occi::Date&, std::string&, std::string&, std::string&, std::string&, std::string&, std::string)' /app/smsprev4/src/NewCore/piliang_src_cluster_2023/plcb_2/src/util.cpp:1107: undefined reference to `updatePreCB(inpackage*, oracle::occi::Date, std::string, std::string, std::string&)' /app/smsprev4/src/NewCore/piliang_src_cluster_2023/plcb_2/src/util.cpp:1201: undefined reference to `updatePreCB(inpackage*, oracle::occi::Date, std::string, std::string, std::string&)' collect2: error: ld returned 1 exit status
07-25

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值