将while循环转换为do while循环

时间:2014-12-18 08:48:55

标签: c++ string replace while-loop find

这是一个用父字符串中的另一个单词(strng)替换特定单词(字符串)的所有实例的函数。

void clean(std::string &s,const std::string oldVal,const std::string newVal){
    std::string::size_type pos = 0;

    while((pos = s.find(oldVal,pos)) != std::string::npos){
        s.replace(pos,oldVal.size(),newVal);
        pos += newVal.size();
    }
}

我对C ++很陌生,我发现while条件有点难以理解。所以我想让这段代码更具可读性。我试着把它变成do while循环。但是,程序崩溃了。抛出out_of_range异常。
我的代码出了什么问题?我使用相同的字符串来检查这两个函数。

void clean2(std::string &s,const std::string oldVal,const std::string newVal){
    std::string::size_type pos = 0;
    do{
        pos = s.find(oldVal,pos);
        s.replace(pos,oldVal.size(),newVal);
        pos += newVal.size();
    }while(pos != std::string::npos);
}

3 个答案:

答案 0 :(得分:2)

这个条件

pos != std::string::npos

你必须在声明之后检查

pos = s.find(oldVal,pos);

否则你可以使用pos的无效值。

因此,在这种情况下,while循环看起来比循环更好。:)

您可以使用for循环重写函数,而不是将while循环替换为do-while循环。例如

void clean(std::string &s,const std::string oldVal,const std::string newVal)
{
    for ( std::string::size_type pos = 0; 
          ( pos = s.find( oldVal, pos ) ) != std::string::npos;
          pos += newVal.size() )
    {

        s.replace( pos, oldVal.size(), newVal );
    }
}

答案 1 :(得分:1)

有一个原因是while和do-while循环都存在,并且它不仅仅是为了便于阅读。
主要区别在于检查条件的时间 以前的版本按照find - >的顺序工作。测试 - >更换
您的版本按照find - >的顺序工作。替换 - >测试。

您可以做的是在替换之前添加if,以在尝试替换之前检查相同的循环条件。但是,与原始IMO相比,它的效率和可读性都较低。

答案 2 :(得分:1)

你需要两个:

"当找不到字符串时不调用replace"并且"不将newVal.size()添加到pos"何时找不到字符串。因此,如果在do-while-loop中需要另一个

换句话说:

void clean2(std::string &s,const std::string oldVal,const std::string newVal){
    std::string::size_type pos = 0;
    do{
        pos = s.find(oldVal,pos);
        if (pos != std::string::npos)
        {
            s.replace(pos,oldVal.size(),newVal);
            pos += newVal.size();
        }
    }while(pos != std::string::npos);
}

或者,您可以这样做:

 while(true)
 {
     pos = s.find(oldVal,pos);
     if (pos != std::string::npos)
     {
         s.replace(pos,oldVal.size(),newVal);
         pos += newVal.size();
     }
     else 
     {
         break;
     }
 }

或同一主题的许多其他变体。