QM Adams
QM Adams

Reputation: 73

How to erase non-alphabet characters from a string without going out of range

I am trying to this function to return without numbers, spaces, or other characters and I am supposed to use the .erase function. I understand that my loop keeps going out of range, but I have no clue how to fix it and I've been stuck on this for a while. If the user types "dogs are a lot of fun" and I need the function to return and output "dogsarealotoffun" Thanks for the help.

#include <iostream>
#include <cctype>
#include <cstring>

using namespace std;

//function to output string without spaces, numbers, or punctuations        
string alphabetOnly (string input){
    int size;
    int i= 0;
    size = (int)input.size();

    while (input[i] < size){
        if (isalpha(input[i])){
            i++;
        }         
        else
            input.erase(input[i]);
    }
    return input;
}

int main() {
    string input;

    cout << "Enter a string to test: ";
    getline(cin, input);

    cout << "alphabetOnly: " << alphabetOnly(input) << endl;
}

Upvotes: 2

Views: 58

Answers (3)

9Breaker
9Breaker

Reputation: 724

EDITED: I was too hasty in my previous answer (as I am learning I need to speak from tested code rather than off the top of my head) and needed to debug. The problem is in the else case you need to erase the char, NOT increment i because the length of the string just changed, and also since the length of the string changed you need to reset size to be the new length. Sorry for the hasty answer earlier, I was speaking without actually using the compiled code.

#include <iostream>
#include <cctype>
#include <string>


//function to output string without spaces, numbers, or punctuations
std::string alphabetOnly (std::string input){
    int size;
    int i= 0;
    size = (int)input.size();

    while (i < size){
        if (isalpha(input[i])){
            i++;
        }
        else{
            input.erase(i,1);
            //do not increment i here since the index changed becauase of erase
            size = (int)input.size();
        }
    }
    return input;
}

int main() {
    std::string input;

    std::cout << "Enter a string to test: ";
    std::getline(std::cin, input);
    std::cout << input;

    std::cout << "alphabetOnly: " << alphabetOnly(input) << std::endl;


    return 0;
}

enter image description here

Upvotes: 1

RobertGBJones
RobertGBJones

Reputation: 101

There's quite a few things wrong with your code, but to start with here's your main error corrected.

#include <iostream>
#include <cctype>
#include <cstring>

using namespace std;

//function to output string without spaces, numbers, or punctuations
string alphabetOnly (string input){
int size;
int i= 0;
size = (int)input.size();

while (i < size){
    if(isalpha(input[i]))
    {
        i++;
    }
    else
       input.erase(input.begin( ) + i );
}
return input;
}

int main() {
string input;

cout << "Enter a string to test: ";
getline(cin, input);

cout << "alphabetOnly: " << alphabetOnly(input) << endl;
}

But this is awfully inefficient because you swhift all the remaining unchecked characters each time you delete.

You should use something like

input.erase( remove_if( input.begin(), input.end(), not( isalpha ) ), input.end( ));

This is known as the remove-erase idiom, whihc you can lookup anywhere.

Upvotes: 0

Richard Hodges
Richard Hodges

Reputation: 69912

something like this:

#include <iostream>
#include <string>
#include <algorithm>

//function to output string without spaces, numbers, or punctuations        
std::string alphabetOnly (std::string input)
{
    auto not_alpha = [](char c) { return !std::isalpha(c); };
    input.erase(std::remove_if(begin(input), 
                               end(input), 
                               not_alpha), 
                std::end(input));
    return input;
}

int main() {
    std::string input;

    std::cout << "Enter a string to test: ";
    getline(std::cin, input);

    std::cout << "alphabetOnly: " << alphabetOnly(input) << std::endl;
}

http://coliru.stacked-crooked.com/a/340465d41ecd8c8e

Upvotes: 0

Related Questions