防止循环内外的代码重复

时间:2011-12-19 19:16:30

标签: c++ loops code-duplication

我在重写循环时遇到问题:

else if( "d" == option || "debug" == option )
{
    debug(debug::always) << "commandline::set_internal_option::setting debug options: "
                         << value << ".\n";
    string::size_type index = 0;
    do
    {
        const string::size_type previous_index = index+1;
        index=value.find( ',', index );
        const string item = value.substr(previous_index, index);
        debug::type item_enum;
        if( !map_value(lib::debug_map, item, item_enum) )
            throw lib::commandline_error( "Unknown debug type: " + item, argument_number );

        debug(debug::always) << "commandline::set_internal_option::enabling " << item
                             << " debug output.\n";
        debug(debug::always) << "\n-->s_level=" << debug::s_level << "\n";
        debug::s_level = static_cast<debug::type>(debug::s_level ^ item_enum);
        debug(debug::always) << "\n-->s_level=" << debug::s_level << "\n";
    } while( index != string::npos );
}

value类似于string("commandline,parser"),问题是在第一次运行时,我需要substr(previous_index, index),但在每次后续迭代中,我都需要substr(previous_index+1, index)来跳过逗号。有一些简单的方法我会忽略,还是我必须在循环外重复调用find进行初始迭代?

5 个答案:

答案 0 :(得分:4)

由于您的目标是防止代码重复:

std::vector<std::string> v;
boost::split(v, value, [](char c) { c == ','; });

如果您想创建自己的分割功能,可以执行以下操作:

template<typename PredicateT>
std::vector<std::string> Split(const std::string & in, PredicateT p)
{
    std::vector<std::string> v;
    auto b = in.begin();
    auto e = b;
    do {
        e = std::find_if(b, in.end(), p);
        v.emplace_back(b,e);
        b = e + 1;        
    } while (e != in.end());

    return v;
}

答案 1 :(得分:3)

为什么不在previous_index之后更新substr

string::size_type index = 0;
string::size_type previous_index = 0;
do {
  index=value.find( ',', previous_index );
  const string item = value.substr(previous_index, index);
  previous_index = index+1;
} while( index != string::npos );

未经检查,但这应该可以解决问题(只有一个内存字)。

答案 2 :(得分:1)

-1开始?

string::size_type index = -1;
do
{
    const string::size_type previous_index = index + 1;
    index=value.find(',', previous_index);
    const string item = value.substr(previous_index, index - previous_index);
} while( index != string::npos );

答案 3 :(得分:0)

一个愚蠢的(有点不可读的)解决方案是这样的:

string::size_type once = 0;
/* ... */
const string::size_type previous_index = index+1 + (once++ != 0); // or !!once

答案 4 :(得分:0)

首先,我认为这是一个小错误:

在您的代码中,如果表达式index=value.find( ',', index );已经是字符串中逗号字符的索引,则表达式index不会更改while( index != string::npos );的值(除了第一次循环迭代)。

因此,您可能希望将while( index++ != string::npos );替换为previous_index = index+1,将previous_index = index替换为string::size_type index = 0; do { const string::size_type previous_index = index; index = value.find( ',', index ); const string item = value.substr(previous_index, index - previous_index); } while( index++ != string::npos );

这也应该解决你原来的问题。

澄清:

{{1}}