一、 目的
c++标准库里std::string或std::wstring不提供字符串分割操作,本文旨在提供源码实现该操作。
二、 源码实现
1. 源码结构:
封装到一个类CStringHelper里,类包含要分离的字符串的常量引用,类的所有操作均不影响源母串;
类CStringHelper是一个模板类,其模板参数是字符串的字符元素类型;
所有分离出来的结果都按顺序放到std::vect里面。
2. 功能实现:
#ifndef __STRINGHELPER_H__
#define __STRINGHELPER_H__
/*************************************************
Copyright: mlizhi.com
Author: Juncheng Lin
Date: 2018-01-08
Description:字符串分割
**************************************************/
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
template<typename TChar = char>
class CStringHelper
{
public:
//要处理的字符串类型,以TChar为元素
typedef std::basic_string<TChar, std::char_traits<TChar>, std::allocator<TChar> > TString;
typedef std::basic_stringstream<TChar, std::char_traits<TChar>, std::allocator<TChar> > TStringStream;
typedef std::basic_istringstream<TChar, std::char_traits<TChar>, std::allocator<TChar> > TIStringStream;
typedef std::basic_ostringstream<TChar, std::char_traits<TChar>, std::allocator<TChar> > TOStringStream;
/**
功能: 构造函数
参数: 要处理的母串
*/
CStringHelper(const TString &str ): m_str(str)
{
}
/**
功能: 分割母串
参数:
@separatorCharSet 分隔符字符集
返回: 分离后的子串
*/
std::vector<TString> Split(const TString &separatorCharSet) const
{
if(separatorCharSet.empty())
{
std::vector<TString> vctRet;
vctRet.push_back(m_str);
return vctRet;
}
return GenericSplit(separatorCharSet, IndexOf<const TString &>, IndexNotOf<const TString &>);
}
/**
功能: 分割母串
参数:
@chSeparator 分隔符
返回: 分离后的子串
*/
std::vector<TString> Split(TChar chSeparator) const
{
return GenericSplit(chSeparator, IndexOf<TChar>, IndexNotOf<TChar>);
}
/**
功能: 获取子串
参数:
@charsSet 子串包含的字符集
返回: 分离后的子串
*/
std::vector<TString> GetSubStrings(const TString &charsSet) const
{
if(charsSet.empty())
return std::vector<TString>();
return GenericSplit(charsSet, IndexNotOf<const TString &>, IndexOf<const TString &>);
}
/**
功能: 获取子串值
参数:
@outValues 作为输出,分离后的值
@charsSet 子串包含的字符集
返回: 无
*/
template<typename TValue>
void GetValues(std::vector<TValue> &outValues, const TString &charsSet) const
{
std::vector<TString> vctSubStrings(GetSubStrings(charsSet));
std::for_each(vctSubStrings.begin(), vctSubStrings.end(), [&outValues](const TString &strVal){
TIStringStream tiss(strVal);
TValue val;
tiss >> val;
outValues.push_back(val);
});
}
~CStringHelper(void)
{
}
template<typename TSeparator, typename TFuncFind, typename TFuncFindNod>
/**
功能: 通用分割母串
参数:
@separator 分割符
@pfuncFind 查找分隔符的方法
@pfuncFindDismatch 查找非分隔符的方法
返回: 分离后的子串
*/
std::vector<TString> GenericSplit(TSeparator separator, TFuncFind pfuncFind, TFuncFindNod pfuncFindDismatch) const
{
std::vector<TString> vctRet;
TString::size_type iBegin = pfuncFindDismatch(m_str, separator, 0);
while (iBegin != std::string::npos)
{
TString::size_type iEnd = pfuncFind(m_str, separator, iBegin);
if(iEnd == TString::npos)
break;
vctRet.push_back(m_str.substr(iBegin, iEnd - iBegin));
iBegin = pfuncFindDismatch(m_str, separator, iEnd);
}
if(iBegin != std::string::npos)
{
vctRet.push_back(m_str.substr(iBegin));
}
return vctRet;
}
template<typename TData>
static typename TString::size_type IndexOf(const TString &str, TData dst, typename TString::size_type iBegin)
{
return str.find_first_of(dst, iBegin);
}
template<typename TData>
static typename TString::size_type IndexNotOf(const TString &str, TData dst, typename TString::size_type iBegin)
{
return str.find_first_not_of(dst, iBegin);
}
protected:
const TString & m_str; //母串的引用
};
#endif
三、使用实例
std::string str("123;456 7890.");
CStringHelper<> helper(str);
//std::vector<std::string> vctSubStrings(helper.Split("; ."));
//std::for_each(vctSubStrings.begin(), vctSubStrings.end(), [](const std::string &str){
// std::cout << str << std::endl;
//});
std::vector<int> vctData;
helper.GetValues(vctData, "1234567890");
std::for_each(vctData.begin(), vctData.end(), [](int val){
std::cout << val << std::endl;
});