I am attempting to remove all double spaces from my string so that only single spaces remain:

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

it finds the first double space, triggering the while statement. It then takes the first space, adds 1 to it and sets the two spaces to one space. Then it checks again.

The problem is that the loop never ends – for example if I put “hello ” doubleSpace would never be set to -1.


std::string::find_first_of only searches until it finds one of the characters in the input string, so as you pass it " ", it’ll effectively only search for " " – see the documentation here:

Searches the string for the first character that matches any of the characters specified in its arguments.

You should use std::string::find instead, which searches for the first instance of the entire substring:

Notice that unlike member find_first_of, whenever more than one character is being searched for, it is not enough that just one of these characters match, but the entire sequence must match.

You’re also replacing only the first space with a space (sString.replace(doubleSpace, 1, " "), which means your output will still contain double spaces. Just use std::string::erase instead, to erase just the first space.

This means your code snippet should look more like:

std::size_t doubleSpace = sString.find("  ");
while (doubleSpace != std::string::npos)
    sString.erase(doubleSpace, 1);
    doubleSpace = sString.find("  ");


Here is an alternative take that returns copy with only single spaces in it:

#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

As suggested by @hnefatl this approach could also be more efficient (see comment below)


I see two errors in your code. The first is that find_first_of() only searches for one of the characters you supply so, in your case, it will only be looking for single spaces. Secondly you only replace one space, not two.

This should fix both those problems:

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;

NOTE: By beginning the subsequent searches from the place you found your last space, this version should be much more efficient. The longer the string the bigger the savings.


This alternative uses const time operations of back(), pop_back(), push_back(), empty(), and 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;

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *