Hi, me again!

I wish to tidy up strings from user input. I have done a bit of research and have most of this working except the tricky bit - converting all/any whitespace between words to 1 ' ' char.

For instance, using hyphen to represent spaces..
---John-----MacDonald-

should end up as

John-MacDonald

Here is my code, it is malfunctioning and I've been debugging but can't see where the fault lies, except that the str.erase (i) bit doesn't seem to work as I expect. I expect it to remove one character at position i. but it doesn't, it chops off the rest of the string normally.

void trimString(string &str)
{
  // trim Leading whitespace
  // inline int ? TODO

  // str = "  345  89"
  int i = 0;
  do
    if (str[i] != ' ' && str[i] != '\t')
      break;
  while (++i <= str.size());
  str.erase(0, i);  // now str = "345  89"

  // trim trailing whitespace
  i = str.size();
  while (i-- >= 0)
    if (str[i] != ' ' && str[i] != '\t')
      break;
  str.resize(++i); // no whitespace at end so str = "345  89"
  
  // trim each remaining whitespace to 1 character
  i = 0;
  while (++i < str.size()-1 /* No check of last char needed*/) {
    // first i==1 as first char != ' '
    if (str[i] == ' ' || str[i] == '\t') {
      cout << i; // Sanity check, correct value
      ++i;
      cout << i; // Sanity check, correct value
      if (str[i] == ' ' || str[i] == '\t') {
        str.erase(i-1); // now str = "345" ERROR!!!
        //str.erase(--i);
        cout << i;
        continue;
      }
    }
  } // end while
}

Instead of doing all this crap with the string, why not just create a new string? isspace() is your friend.

Instead of doing all this crap with the string, why not just create a new string? isspace() is your friend.

Use if (isspace(ch)) to move past whitespaces. Then when find next non whitespace character, copy a space, then the character, then move on?

Still having problems, and the culprit is definelty the string.erase modifier.
Does this modifier have to be called by reference ( I mean by a pointer to a string) and the other statements like newstr do that by default?
Is that the problem?

At the moment
newstr.erase(j) // j=8
wipes the whole string.

string trimString(string str) {
  string newstr;
  int j = 0;
  for (int i=1; i<str.size(); i++) {
    if (isspace(str[i]) && isspace(str[i+1])) {
       newstr[j] = ' ';
       j++;
       i++;
    } 
    else {
      newstr[j] = str[i];
      j++;
    }
  }
  newstr.erase(j);
  return newstr;
}

Why are you erasing anything in the first place?
here's the idea:

1. Increment an iterator until isspace() is false.
2. Increment another iterator until isspace() is true. You now have a word.
3. Add the word and a space to the new string.
4. Rinse and repeat.

Why are you erasing anything in the first place?
here's the idea:

1. Increment an iterator until isspace() is false.
2. Increment another iterator until isspace() is true. You now have a word.
3. Add the word and a space to the new string.
4. Rinse and repeat.

While watching the newstr value in VS debugger,
after newstr[j] = ' ';
the string was updated to be the same length as str and had {" ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ"} as it's value.
(First charcter is a space which it should have copied).
From that I presumed I had to resize the string to the correct value (last increment of j).

I can see your method working, so I'll give that a go.

Still having problems, and the culprit is definelty the string.erase modifier.
Does this modifier have to be called by reference ( I mean by a pointer to a string) and the other statements like newstr do that by default?
Is that the problem?

At the moment
newstr.erase(j) // j=8
wipes the whole string.

Maybe you should look up how string.erase works. This took me 30 seconds to find rather than the two hours you've been posting.

Maybe you should look up how string.erase works. This took me 30 seconds to find rather than the two hours you've been posting.

I did read about all the modifiers etc of the string class, here: http://www.cplusplus.com/reference/string/string/

Just my lecturer in uni never wrote in his notes that I had to have using std::string; in the file.

Like you said I've just spent 2 hours redefining an algorithm when the fault was something I mentioned in the first post. I should have trusted my instincts :'(

Still, nothing like practice to keep you keen :P

This article has been dead for over six months. Start a new discussion instead.