如何从字符串中删除所有双空格

时间:2017-12-30 00:00:48

标签: c++ string

我试图从字符串中删除所有双重空格,以便只剩下一个空格:

while  (doublespace != -1) {
    kstring.replace(doublespace, 1, " ") ;
    doublespace = kstring.find_first_of("  ") ; }

找到第一个双空格,触发while语句。然后它取第一个空格,加1,并将两个空格设置为一个空格。然后再次检查。

问题是循环永远不会结束 - 例如,如果我把“hello”doubleSpace永远不会设置为-1。

4 个答案:

答案 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;