如何正确使用string::erase
How to properly use string::erase
我不确定我是否正确使用 string::erase。我正在尝试创建一个函数来找到一个子字符串并将其从原始字符串中删除。我已经测试过 string:find 有效,但在擦除时,相同的字符串仍然存在。
源文件.cpp
Sentence operator-(const Sentence& arg1, const Sentence& arg2)
{
Sentence result = arg1;
string str = arg1.get_sentence();
string str2 = arg2.get_sentence();
bool found = false;
if (str2.find(str) != std::string::npos) {
found = true;
} else if (found == true) {
str2.erase(str.find(str), str2.size());
}
return str2;
}
如果我们重写
if (str2.find(str) != std::string::npos) {
found = true;
} else if (found == true) {
str2.erase(str.find(str), str2.size());
}
对于编译器如何解析它,它会像
if (str2.find(str) != std::string::npos) {
found = true;
} else {
if (found == true) {
str2.erase(str.find(str), str2.size());
}
}
现在很容易看出 else
分支中的条件永远不会为真。如果 else
分支发生,那么另一个分支永远不会发生,并且 found
仍然是 false
.
使用您显示的代码,您可以跳过 found
变量,直接执行
if (str2.find(str) != std::string::npos) {
str2.erase(str.find(str), str2.size());
}
您的代码中有两个错误。
首先 你搞砸了 if
语句逻辑,以至于擦除语句从未被执行(正如另一个答案中指出的那样)。
其次你用错了std::string::erase()
。第一个参数应该是要删除的第一个字符的索引,第二个参数是要删除的字符总数。
由于您已经搜索了子字符串,因此您可以重新使用该信息以用于 erase
。因此,我们代码的正确版本是
auto pos = str.find(sub);
if(pos != std::string::npos)
str.erase(pos,sub.size());
如果要删除 所有 次出现的子字符串,可以使用 for
循环:
for(auto pos=str.find(sub); pos!=std::string::npos; pos=str.find(sub))
str.erase(pos,sub.size());
如果你想从原来的 string.This 中删除所有相同的子字符串可能有效。
while(str2.find(str) != std::string::npos) {
str2.erase(str2.find(str), str2.size());//here
}
return str2;//you shouldn't return string, it's not your return type.
str.erase (pos,length); //your choice
//if str="abcdefg"
str.erase(3,2);
//str="abcfg"
或
str.erase (first,last);
//if str="abcdefg"
str.erase(str.begin()+3,str.begin()+5);
//str="abcfg"
如果 str2 是 str 的子串,"str.find(str2);" 将 return 它第一次出现的第一个位置。
str="Thank you";
str2="you";
str.find(str2);//return 6
所以
str2.erase(str.find(str), str2.size());
应该是
str2.erase(str2.find(str), str2.size());
希望对您有所帮助。
我不确定我是否正确使用 string::erase。我正在尝试创建一个函数来找到一个子字符串并将其从原始字符串中删除。我已经测试过 string:find 有效,但在擦除时,相同的字符串仍然存在。
源文件.cpp
Sentence operator-(const Sentence& arg1, const Sentence& arg2)
{
Sentence result = arg1;
string str = arg1.get_sentence();
string str2 = arg2.get_sentence();
bool found = false;
if (str2.find(str) != std::string::npos) {
found = true;
} else if (found == true) {
str2.erase(str.find(str), str2.size());
}
return str2;
}
如果我们重写
if (str2.find(str) != std::string::npos) {
found = true;
} else if (found == true) {
str2.erase(str.find(str), str2.size());
}
对于编译器如何解析它,它会像
if (str2.find(str) != std::string::npos) {
found = true;
} else {
if (found == true) {
str2.erase(str.find(str), str2.size());
}
}
现在很容易看出 else
分支中的条件永远不会为真。如果 else
分支发生,那么另一个分支永远不会发生,并且 found
仍然是 false
.
使用您显示的代码,您可以跳过 found
变量,直接执行
if (str2.find(str) != std::string::npos) {
str2.erase(str.find(str), str2.size());
}
您的代码中有两个错误。
首先 你搞砸了 if
语句逻辑,以至于擦除语句从未被执行(正如另一个答案中指出的那样)。
其次你用错了std::string::erase()
。第一个参数应该是要删除的第一个字符的索引,第二个参数是要删除的字符总数。
由于您已经搜索了子字符串,因此您可以重新使用该信息以用于 erase
。因此,我们代码的正确版本是
auto pos = str.find(sub);
if(pos != std::string::npos)
str.erase(pos,sub.size());
如果要删除 所有 次出现的子字符串,可以使用 for
循环:
for(auto pos=str.find(sub); pos!=std::string::npos; pos=str.find(sub))
str.erase(pos,sub.size());
如果你想从原来的 string.This 中删除所有相同的子字符串可能有效。
while(str2.find(str) != std::string::npos) {
str2.erase(str2.find(str), str2.size());//here
}
return str2;//you shouldn't return string, it's not your return type.
str.erase (pos,length); //your choice
//if str="abcdefg"
str.erase(3,2);
//str="abcfg"
或
str.erase (first,last);
//if str="abcdefg"
str.erase(str.begin()+3,str.begin()+5);
//str="abcfg"
如果 str2 是 str 的子串,"str.find(str2);" 将 return 它第一次出现的第一个位置。
str="Thank you";
str2="you";
str.find(str2);//return 6
所以
str2.erase(str.find(str), str2.size());
应该是
str2.erase(str2.find(str), str2.size());
希望对您有所帮助。