这是一个用父字符串中的另一个单词(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);
}
答案 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;
}
}
或同一主题的许多其他变体。