0

Lets say I have something as such:

string s;
cout << "Enter a word:";
cin >> s;

//clean s

print(s);

If someone enters something like --sorry or what,, I want to be able to 'clean' the string before passing it into the function which prints out the word. Cleaning a string is making it a word. In this case, a word would be defined as any consecutive strings of letters (also apostrophes can be there, for example don't is one word. So getting rid of anything else in there.

I was thinking something like this:

string s;
cout << "Enter a word:";
cin >> s;

//clean s
string s2;
for (int i = 0; i < s.length(); i++)
   if(isalpha(s[i]) || s[i] = "'")
       s2[i] = s[i];

print(s2);

But this makes my program not work, so I need to figure out another way to do this.

Thank you!

edit:

string s;
cout << "Enter a word:";
cin >> s;

//clean s
s.erase(remove_if(s.begin(), s.end(), [](char c) {return !isalpha(c) || 
c == '\'' || c == '\-' || c == ','; }));

print(s);

Edit (latest):

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main(){

    string s;
    cout << "Enter a word:";
    cin >> s;

    //clean s
    s.erase(remove_if(s.begin(), s.end(), [](char c)
    {
        return !isalpha(c) || c == '\'' || c == '-' || c == ',' || c == ';' || c == ':';
    }));

    cout << s;
}
mojo1mojo2
  • 1,062
  • 1
  • 18
  • 28
StacksAndParsing
  • 119
  • 1
  • 11
  • you access `s2` out of range... and you should have 2 indexes – bolov May 06 '16 at 17:43
  • Is C++11 and [`regex_replace`](http://en.cppreference.com/w/cpp/regex/regex_replace) an option? – tadman May 06 '16 at 17:44
  • You can set the local to treat everything but characters and apostrophes as space (thus they will be ignored when read with `operator>>`). http://stackoverflow.com/a/6154217/14065 – Martin York May 06 '16 at 17:52

2 Answers2

3

You'll want to use the erase-remove idiom:

s.erase(
    std::remove_if(s.begin(), s.end(), [](char c) { return ???; }),
    s.end()
    );

Fill in the ??? with the appropriate filter for characters you want to get rid of. Perhaps something like:

[](char c){ return !isalpha(c) && c != '\''; }
Barry
  • 286,269
  • 29
  • 621
  • 977
  • I tried `s.erase(remove_if(s.begin(), s.end(), [](char c) {return !isalpha(c) && c != '-', ','; }));` but now it is removing the first character of the string and there are still commas and stuff – StacksAndParsing May 06 '16 at 18:03
  • @StacksAndParsing Notice which arguments I am passing to `erase()`. Also what are you doing with that comma there, that's totally wrong. – Barry May 06 '16 at 18:05
  • @StacksAndParsing Your filter right now is basically `return true;` – Barry May 06 '16 at 18:10
  • Like this: `s.erase(remove_if(s.begin(), s.end(), [](char c) {return !isalpha(c) && c != '\'' && c!='-' && c!=','; }));`. I can see the words now but it didn't get rid of the other stuff. – StacksAndParsing May 06 '16 at 18:11
2

The problem is that s2 is default constructed. That means it has a size of 0. When you try to store characters into it with

for (int i = 0; i < s.length(); i++)
   if(isalpha(s[i]) || s[i] = "'")
       s2[i] = s[i];

You are attempting to access memory that doesn't exist. What you can do is use the += operator of string to add the valid characters of s1 into s2 like

for (int i = 0; i < s.length(); i++)
   if(isalpha(s[i]) || s[i] = "'")
       s2 += s[i];

You could also use the erase-remove idiom and just modify s1 and not even have s2. You could do that like

s1.erase(std::remove_if(s1.begin(), s1.end(), 
                        [](char ch){ return !(std::isalpha(ch) || ch == '\''); }), 
         s1.end());
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • if I try to do it without the erase-remove idiot it gives me an error message because `s[i] = " ' "` doesn't work (a value of type const char* cannot be assigned to an entity of type char). I tried with two equal signs as well and it doesn't work still – StacksAndParsing May 06 '16 at 18:01
  • @StacksAndParsing What is the updated code you used? You should just be able to copy and paste what I wrote. – NathanOliver May 06 '16 at 18:03
  • @StacksAndParsing Your `c != '-', ','` should be `c != '\''` like I have in my example – NathanOliver May 06 '16 at 18:09
  • @StacksAndParsing Just take the code I wrote and replace `s1` with `s` and it should work. – NathanOliver May 06 '16 at 18:11
  • @StacksAndParsing It looks like you are missing the end iterator in the erase call. [This example program](http://coliru.stacked-crooked.com/a/d50d1df4eeb73b5f) does exactly what you asked for. – NathanOliver May 06 '16 at 18:47