John Wrgzl
John Wrgzl

Reputation: 11

Creating a function that deletes a certain character from a string. What is wrong with my program?

I am trying to delete all G's from a string. I need to use a pointer, but my problem is I don't know what to replace the found G's with. I did not know an empty character constant ('') would not compile. How can I remove the character keeping in line with this code?

   void deleteG(char cString[])
{
    char *ptr;
    ptr = cString;
    while (*ptr != '\0')
    {
        if (*ptr == 'g' || *ptr == 'G')
        {
            *ptr = ' ';
        }
        ptr++;


}

}

Upvotes: 1

Views: 247

Answers (4)

Tas
Tas

Reputation: 7111

As @Captain Obvlious points out, your while loop never ends because unless a letter is a 'g' or 'G' it will never increment the pointer. This is fairly easy to determine if you put a breakpoint in, or even use a std::cout on the letter being evaluated.

The solution of course is to change your while loop to the following:

while (*ptr != '\0')
{
    if (*ptr == 'g' || *ptr == 'G')
    {
        *ptr = *(ptr+1);
    }
    ptr++;
}

Whilst this solves the problem of the infinite loop, an even better solution would be to use the standard library: std::string! Because I'm not 100% sure of what you are trying to accomplish, I'll provide two examples:

Using the standard library to remove all upper-case letters

If your goal was to remove all upper-case characters, consider the following use of the standard library:

bool IsUpper(char c)
{
    return !!std::isupper(c);
}

int main()
{
    std::string test = "Hello World :D";
    test.erase(std::remove_if(test.begin(), test.end(), IsUpper), test.end());
    return 0;
}

This uses std::string::erase and std::remove_if to remove all upper-case letters from the string. std::remove_if takes a start and end iterator (we give it the start and end of our test string) and a predicate (our function IsUpper) which will be called for each element in the container (in this case, each char0 in the std::string). If the predicate (IsUpper) returns true for a char, that char is moved to the back of the container. std::remove_if will continue to do this until it reaches the end, where it will then return an iterator to the beginning of the offending characters (now at the end of the string).
This iterator is then used by std::string::erase, which takes a start and end iterator (similar to std::remove_if) and erases the elements in that range (in this case, the start of the offending characters to the end of the string).
You will be left with only "ello orld :"

Note also our predicate IsUpper uses another standard library function std::isupper to determine if a char is upper-case or not.

Using the standard library to remove all g's

If, like your function name deleteG suggests, you were trying to remove all instances of g from your string, consider:

bool IsG(char c)
{
    return c == 'g' || c == 'G';
}

int main()
{
    std::string test = "GHelgglo gWorlgGd";
    test.erase(std::remove_if(test.begin(), test.end(), IsG), test.end());
    return 0;
}

Similar to above, but we have swapped out our predicate (and test string) for a function that tells us whether a certain character is a g or not: aptly named IsG.
You will be left with "Hello World"

Upvotes: 1

Katie
Katie

Reputation: 452

I am not much familiar with c++. Try to increment the pointer outside the if statements, not inside it. Then it will not enter in an infinite while loop

Upvotes: 0

Tony Delroy
Tony Delroy

Reputation: 106086

I'd recommend something like this...

void deleteAlpha(char cString[])
{
    const char *from = cString;
    char* to = cString;

    do
    {
        while (isalpha(*from))
            ++from;
    }
    while (*to++ = *from++);
}

Note that from iterates over the string, skipping alpha characters, while to tracks the location that the next non-alpha character should be "compacted" to. The while loop condition carefully copies the terminating NUL even as it evaluates false and finishes the iteration.

Upvotes: 1

Archit Garg
Archit Garg

Reputation: 1012

char* remove(char *s) {
    char *current = s;
    char *r = s; // 
    do {
        if ((*current < 'A') || (*current > 'Z') || (*current < 'a') || (*current > 'z')) {
            *r++ = *current;
        }
    } while (*current++ != 0);
    return s;
}

Upvotes: 0

Related Questions