String non-alphabet deletion

This program is designed to show the input is a palindrome or not. This this case, I attempt to remove the non-alphabet by using str.erase(),but show how the compiler give me an out of range error. How to fix this? or any shortcut method to do the non-alphabet removal? And also, if I only want numbers instead of alphabet, how to modify it?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
  #include <iostream>
#include <string>
using namespace std;

void deletion(string &text)
{
	int found;
	for(int i = 0; i < 100; i ++)
		{
			found = text.find(" ");
			text.erase(found,1);
			/*found = text.find(",");
			text.erase(found,1);
			found = text.find(".");
			text.erase(found,1);
			found = text.find(":");
			text.erase(found,1);
			found = text.find("!");
			text.erase(found,1);
			found = text.find("@");
			text.erase(found,1);
			found = text.find("#");
			text.erase(found,1);
			found = text.find("$");
			text.erase(found,1);
			found = text.find("%");
			text.erase(found,1);
			found = text.find("^");
			text.erase(found,1);
			found = text.find("&");
			text.erase(found,1);
			found = text.find("*");
			text.erase(found,1);
			found = text.find("(");
			text.erase(found,1);
			found = text.find(")");
			text.erase(found,1);
			found = text.find("-");
			text.erase(found,1);
			found = text.find("+");
			text.erase(found,1);
			found = text.find("=");
			text.erase(found,1);
			found = text.find("|");
			text.erase(found,1);
			found = text.find("_");
			text.erase(found,1);
			found = text.find("0");
			text.erase(found,1);
			found = text.find("1");
			text.erase(found,1);
			found = text.find("2");
			text.erase(found,1);
			found = text.find("3");
			text.erase(found,1);
			found = text.find("4");
			text.erase(found,1);
			found = text.find("5");
			text.erase(found,1);
			found = text.find("6");
			text.erase(found,1);
			found = text.find("7");
			text.erase(found,1);
			found = text.find("8");
			text.erase(found,1);
			found = text.find("9");
			text.erase(found,1);
			found = text.find("{");
			text.erase(found,1);
			found = text.find("}");
			text.erase(found,1);
			found = text.find("[");
			text.erase(found,1);
			found = text.find("]");
			text.erase(found,1);
			found = text.find(";");
			text.erase(found,1);
			found = text.find("'");
			text.erase(found,1);
			found = text.find("/");
			text.erase(found,1);
			found = text.find("?");
			text.erase(found,1);
			found = text.find("<");
			text.erase(found,1);
			found = text.find(">");
			text.erase(found,1); */
		}
}

int main()
{
	cout << "Input -> ";
	string text;
	getline(cin, text);
	int i = text.length() - 1;
	bool valid = true;
	deletion(text);
	for(int j = 0 ; j < i ; j++ )
	{		
		if(tolower(text[j] != text[i-j])) //for case insensitive
		{
			valid = false;	
		}
	}
	if(valid)
	{
		cout <<"Yes"<< endl;
	}
	else
	{
		cout<<"No"<<endl;
	}
   return 0;
}
1
2
3
	int i = text.length() - 1;
	bool valid = true;
	deletion(text);


You set i to text.length()-1, then you reduce the length of text. When you enter the for loop, i will be an invalid index into text.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <cctype>
#include <string>

std::string extractAlpha(const std::string& text)
{
    std::string result;

    for (std::size_t i = 0; i < text.length(); ++i)
        if (std::isalpha(text[i]))
            result += std::tolower(text[i]);

    return result;
}

int main()
{
    std::cout << "> ";

    std::string text;
    std::getline(std::cin, text);

    text = extractAlpha(text);

    unsigned i = 0, j = text.length() - 1;

    while (i < j && text[i] == text[j])
        ++i, --j;

    if (i <= j)
        std::cout << "Yes";
    else
        std::cout << "No";

    std::cout << std::endl;
}
Something like this?:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <windows.h>
#include <iostream>
#include <string>

void strip(std::string& string) {
	unsigned size = string.size();
	std::string stripped;
	for(unsigned int i=0; i<size; ++i) {
		if((string[i]>=97 && string[i]<=122) || (string[i]>=65 && string[i]<=90)) {
			stripped.push_back(string[i]);
		}
	}
	string=stripped;
}

int main() {
	SetConsoleTitleA("String Strip");
	std::string string;
	std::cout << "Enter String: ";
	std::cin >> string;
	std::cout << std::endl << "Original String:\t" << string << std::endl;
	strip(string);
	std::cout << "Stripped String:\t" << string << std::endl;
	std::cin.sync();//ugh
	std::cin.get();//ugh
	return 0;
}
Thank you for the logic correction cause by the sequences.
however, I couldn't learn too much library at once, considering cctype are not yet touched...

Btw, is there any method to remove the characters based on ASCII values by range instead of doing one by one? (with library string,cstring,cstdlib,iostream,iomanip and using name space std (it is so difficult to read since our tutor simply it from the 1st day we learn and now we all getting use to it.))
hank you for the logic correction cause by the sequences.
however, I couldn't learn too much library at once, considering cctype are not yet touched...

That's odd, since you were already using it in the form of tolower. You just weren't including the correct header.


Btw, is there any method to remove the characters based on ASCII values by range instead of doing one by one?

Not unless you want to learn too much library at once. =P

But, no matter which library algorithm or construct you use, it is going to be dealing with one character at a time internally.
If you may not use functions from <cctype> you can write the function for example the following way

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void deletion( std::string &text )
{
	std::string::size_type j = 0;
	for (  std::string::size_type i = 0; i < text.size(); ++i )
	{
		if ( 'a' <= text[i] && text[i] <= 'z' || 'A' <= text[i] && text[i] <= 'Z' )
		{
			text[j++] = text[i];
		}
	}

	text.erase( j );

}
Without using <cctype> and limiting alphabetic characters to those in the basic source character set:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <string>
#include <iostream>

int main()
{
    std::string original_str = "String to be TESted" ;
    //std::getline( std::cin, original_str ) ;

    static const std::string alpha_upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
    static const std::string alpha_lower = "abcdefghijklmnopqrstuvwxyz" ;

    std::string sanitized_str ;
    for( char c : original_str ) // for each character in original_str
    {
        auto pos = alpha_upper.find(c) ;
        if( pos != std::string::npos ) // it is an upper case character
        {
            sanitized_str += c ; // append this char to the result
        }
        else
        {
            pos = alpha_lower.find(c) ;
            if( pos != std::string::npos ) // it is a lower case character
            {
                // append the corresponding upper case char to the result
                sanitized_str += alpha_upper[pos] ; 
            }
        }
    }

    std::cout << original_str << " => " << sanitized_str << '\n' ;

    // check if sanitized_str is a palindrome
    // ...
}
Topic archived. No new replies allowed.