简体   繁体   English

将while循环转换为do while循环

[英]Converting a while loop to a do while loop

Here is a function to replace all the instances of a specific word(string) with another word(strng) in a parent string. 这是一个函数,用父字符串中的另一个单词(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();
    }
}

I am pretty new to C++ and I found the while condition a little difficult to understand. 我对C ++相当陌生,我发现while条件有些难以理解。 So I thought of making this code more readable. 因此,我想到了使此代码更具可读性。 I tried to make it into a do while loop. 我试图使其变成do while循环。 However, the program crashed. 但是,程序崩溃了。 Throwing out_of_range exception. 抛出out_of_range异常。
What's wrong with my code? 我的代码有什么问题? I used the same string to check both functions. 我使用相同的字符串来检查两个功能。

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);
}

This condition 这种情况

pos != std::string::npos

you have to check after statement 您必须在声明后检查

pos = s.find(oldVal,pos);

Otherwise you can use invalid value of pos. 否则,您可以使用pos的无效值。

So the while loop in this case looks better then do while loop.:) 因此,在这种情况下,while循环比while循环看起来更好。

Instead of substituting the while loop for a do-while loop you could rewrite the function using a for loop. 除了用while循环代替do-while循环外,您还可以使用for循环重写函数。 For example 例如

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 );
    }
}

There is a reason that both while and do-while loops exist and it's not just for readability. 原因是while和do-while循环同时存在,这不仅是为了提高可读性。
The main difference is the time that the condition is checked. 主要区别在于检查条件的时间。
The previous versions works in a sequence of find -> test -> replace 以前的版本按查找->测试->替换的顺序工作
Your version works in a sequence of find -> replace -> test. 您的版本按查找->替换->测试的顺序工作。

What you can do is add an if before the replace that checks for the same loop condition before attempting the replace. 您可以做的是在替换之前添加一个if,以在尝试替换之前检查相同的循环条件。 However, that's both less efficient and less readable than the original IMO. 但是,这与原始IMO相比效率较低且可读性较差。

you need to both: 您需要同时:

"not call replace when the string is not found" and "not add newVal.size() to pos" when string is not found. “找不到字符串时不调用替换”和“找不到字符串时不添加newVal.size()到pos”。 So you need another if inside the do-while-loop 因此,如果在do-while循环内,则需要另一个

In other words: 换一种说法:

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);
}

Alternatively, you could do something like this: 或者,您可以执行以下操作:

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

Or many other variants on the same theme. 或同一主题的许多其他变体。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM