我试图从字符串中删除所有双重空格,以便只剩下一个空格:
while (doublespace != -1) {
kstring.replace(doublespace, 1, " ") ;
doublespace = kstring.find_first_of(" ") ; }
找到第一个双空格,触发while语句。然后它取第一个空格,加1,并将两个空格设置为一个空格。然后再次检查。
问题是循环永远不会结束 - 例如,如果我把“hello”doubleSpace永远不会设置为-1。
答案 0 :(得分:6)
std::string::find_first_of
只会在输入字符串中找到一个字符时进行搜索,因此当您将其传递给" "
时,它实际上只会搜索{ {1}} - 请参阅文档here:
在字符串中搜索与其参数中指定的任何字符匹配的第一个字符。
您应该使用std::string::find
来搜索整个子字符串的第一个实例:
请注意,与成员find_first_of不同,每当搜索多个字符时,仅仅其中一个字符匹配是不够的,但整个序列必须匹配。
您还只使用空格(" "
)替换第一个空格,这意味着您的输出仍将包含双倍空格。只需使用std::string::erase
代替,只删除第一个空格。
这意味着您的代码段应该更像:
sString.replace(doubleSpace, 1, " "
答案 1 :(得分:3)
这是一个替代版本,它返回只有一个空格的副本:
#include <iostream>
#include <string>
int main()
{
std::string str = " hello - h e l l o ";
std::string newstr;
size_t beg = 0;
size_t len = str.length();
while (beg < len)
{
size_t end = str.find_first_of(' ', beg) + 1;
newstr += str.substr(beg, end - beg);
beg = str.find_first_not_of(' ', end);
}
std::cout << newstr << std::endl;
return 0;
}
结果:
hello - h e l l o
正如@hnefatl所建议的那样,这种方法也可能更有效(见下面的评论)
答案 2 :(得分:2)
我在代码中看到两个错误。首先,find_first_of()
只搜索您提供的字符的 一个 ,因此,在您的情况下,它只会查找单个空格。其次,您只能替换 一个 空间,而不是两个。
这应解决这两个问题:
std::string& reduce_double_spaces(std::string& s)
{
std::string::size_type pos = s.find(" ");
while (pos != std::string::npos) {
// replace BOTH spaces with one space
s.replace(pos, 2, " ");
// start searching again, where you left off
// rather than going back to the beginning
pos = s.find(" ", pos);
}
return s;
}
注意:从您找到最后一个空格的地方开始后续搜索,此版本应该更有效率。字符串越长,节省的金额越大。
答案 3 :(得分:0)
此替代方法使用back(),pop_back(),push_back(),empty()和size()的常量时间操作,
std::string str = " hello - h e l l o ";
std::string newStr = str; // diag only
std::string Miss; Miss.reserve(str.size());
while ( str.size() > 1 ) // note: str.back() undefined when str.empty()
{
// fetch copy and remove last element
char aKar = str.back(); str.pop_back();
if (! ((' ' == aKar) && // space
( ' ' == str.back()))) // space
{
Miss.push_back(aKar); // not double-space
}
}
assert(1 == str.size()); // optional
while (! Miss.empty() ) // restore str to original order
{
str.push_back (Miss.back()); // copy last element
Miss.pop_back(); // remove last element
}
assert(Miss.empty()); // optional
std::cout << "\n " << __FUNCTION__
<< "\n in: " << newStr
<< "\n out: " << str << std::endl;