仅供参考:没有助益,是的,我 想 重新发明轮子;)
C ++中是否存在某种形式的选择性迭代器(可能)?我想要的是这样分隔字符串:
some:word{or other
变成这样的形式:
some : word { or other
我可以通过两个循环以及find_first_of(“:”)和(“ {”)来做到这一点,但这对我来说似乎效率很低。我认为也许会有一种创建/定义/编写迭代器的方法,该迭代器将使用for_each遍历所有这些值。我担心这会让我为std :: string写一个成熟的自定义方式过于复杂的迭代器类。
所以我想也许这样做可以:
std::vector<size_t> list; size_t index = mystring.find(":"); while( index != std::string::npos ) { list.push_back(index); index = mystring.find(":", list.back()); } std::for_each(list.begin(), list.end(), addSpaces(mystring));
在我看来,这看起来很混乱,而且我很确定存在一种更优雅的方法。但是我想不到。有人有个好主意吗?谢谢
PS:我没有测试发布的代码,只是快速写了我会尝试的代码
更新:在考虑了您所有的答案之后,我想到了这一点,并且按我的喜好:)。这样做假设最后一个字符是一个新行或东西,否则结局{,}或:将不会得到处理。
{
}
:
void tokenize( string &line ) { char oneBack = ' '; char twoBack = ' '; char current = ' '; size_t length = line.size(); for( size_t index = 0; index<length; ++index ) { twoBack = oneBack; oneBack = current; current = line.at( index ); if( isSpecial(oneBack) ) { if( !isspace(twoBack) ) // insert before { line.insert(index-1, " "); ++index; ++length; } if( !isspace(current) ) // insert after { line.insert(index, " "); ++index; ++length; } } }
像往常一样欢迎评论:)
std::string const str = "some:word{or other"; std::string result; result.reserve(str.size()); for (std::string::const_iterator it = str.begin(), end = str.end(); it != end; ++it) { if (isalnum(*it)) { result.push_back(*it); } else { result.push_back(' '); result.push_back(*it); result.push_back(' '); } }
插入版本以加快速度
std::string str = "some:word{or other"; for (std::string::iterator it = str.begin(), end = str.end(); it != end; ++it) { if (!isalnum(*it)) { it = str.insert(it, ' ') + 2; it = str.insert(it, ' '); end = str.end(); } }
请注意,std::string::insert在传递迭代器之前插入,然后将迭代器返回到新插入的字符。分配很重要,因为缓冲区可能已被重新分配到另一个内存位置(迭代器因插入而无效)。另请注意,您无法保留end整个循环,每次插入时都需要重新计算。
std::string::insert
end