下面是一个函数,用于将一个特定单词( 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();
}
}我对C++非常陌生,我觉得自己的情况有点难理解。所以我想让这段代码更易读。我试着把它变成一个并发循环。然而,程序崩溃了。引发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);
}发布于 2014-12-18 08:54:43
这个条件
pos != std::string::npos你必须在声明后检查一下
pos = s.find(oldVal,pos);否则,可以使用pos的无效值。
因此,在本例中,while循环比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 );
}
}发布于 2014-12-18 08:56:03
有一个原因是,while和do-while循环都存在,这不仅仅是为了可读性。
主要的区别是检查条件的时间。
以前的版本按照find ->测试->替换的顺序工作。
您的版本在find ->替换->测试序列中工作。
您可以做的是在替换之前添加一个if,在尝试替换之前检查相同的循环条件。然而,这两种方法的效率和可读性都不如最初的IMO。
发布于 2014-12-18 08:56:37
你们两个都要:
“找不到字符串时不调用replace”,找不到字符串时“未将newVal.size()添加到pos”。因此,如果在do-while-循环中,则需要另一个
换言之:
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;
}
}或者在同一主题上的许多其他变体。
https://stackoverflow.com/questions/27542445
复制相似问题