另一个... 这个应该很容易随着时间的推移添加功能,而不需要更改函数签名,因为我使用了“标志”而不是单独的布尔选项。
utils.h
#include <string>
#include <vector>
namespace utils
{
void ltrim( std::string &s );
void rtrim( std::string &s );
void trim( std::string &s );
enum SplitFlags
{
SPLIT_TRIMMED = 0x01
, SPLIT_NO_EMPTY = 0x02
};
std::vector<std::string> split(
const std::string &s, const char delimiter, const int flags=0 );
}
utils.cpp
#include <sstream>
#include <algorithm>
#include <cctype>
#include <locale>
#include "utils.h"
void utils::ltrim( std::string &s )
{
s.erase( s.begin(), std::find_if( s.begin(), s.end(),
[]( unsigned char ch ) { return !std::isspace( ch ); } ) );
}
void utils::rtrim( std::string &s )
{
s.erase( std::find_if( s.rbegin(), s.rend(),
[]( unsigned char ch ) { return !std::isspace( ch ); } ).base(), s.end() );
}
void utils::trim( std::string &s )
{
rtrim( s );
ltrim( s );
}
std::vector<std::string> utils::split(
const std::string &s, const char delimiter, const int flags )
{
const bool trimmed( flags & SPLIT_TRIMMED )
, noEmpty( flags & SPLIT_NO_EMPTY )
;
std::vector<std::string> tokens;
std::stringstream ss( s );
for( std::string t; getline( ss, t, delimiter ); )
{
if( trimmed ) trim( t );
if( noEmpty && t.empty() ) continue;
tokens.push_back( t );
}
return tokens;
}
示例用法:
const auto parts( utils::split(
" , a g , b, c, ", ',', utils::SPLIT_TRIMMED | utils::SPLIT_NO_EMPTY ) );