1

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++; } 

}

3
  • 4
    Because you only increment ptr when you encounter g or G in the string. What happens if it's not one of those characters hmmmmmm? Commented Aug 3, 2015 at 23:53
  • Try using string type instead of pointers. Commented Aug 3, 2015 at 23:56
  • @CaptainObvlious, I think that should probably be an answer, since it's literally the answer! Commented Aug 4, 2015 at 0:02

4 Answers 4

1

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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"

8 Comments

Note that you shouldn't use sizeof on an array parameter - it will not return the size of the array, as that is not known at compile time.
Thanks @TheDark, I have removed that example. I did try sizeof(cString) and it worked fine (or seemed to).
Note that after the second g in the string, you need to copy *(ptr + 2). In fact, in general, you need two pointers (or two indexes, or a pointer and an index) to do the job properly.
"I did try sizeof(cString) and it worked fine (or seemed to)" just fyi - it will return the size of a char*, rather than strlen() of the text. That's because the cString parameter is treated as a char* parameter (despite the [] notation). That allows the same function to process different length text during different calls. sizeof does work on actual arrays where the dimension is known, such as a local array variable, or when a function parameter is passed a la template <size_t N> void f(T (&a)[N]) { /* sizeof a "works"... */), but then you get an instantiation per size.
Given the test program: int main(void) { char data[] = "abcdefghijABCDEFGHIJ"; char *ptr = data; printf("Before: [[%s]]\n", data); while (*ptr != '\0') { if (*ptr == 'g' || *ptr == 'G') { *ptr = *(ptr+1); } ptr++; } printf("After: [[%s]]\n", data); return 0; }, the output is two lines of data: (1) Before: [[abcdefghijABCDEFGHIJ]] and (2) After: [[abcdefhhijABCDEFHHIJ]]. This isn't what's wanted.
|
0
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; } 

2 Comments

You might want to test that... not going to be pretty. For a start, if ((*current < 'A') || (*current > 'Z') || (*current < 'a') || (*current > 'z')) will always be true....
There's isalpha() from <ctype.h> for testing whether a character is a letter.
0

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

2 Comments

Thanks, I'm out of the infinite loop. Now I'm just looking for a better way to delete G/g characters when I find them then by replacing them with ' ' .
@JohnWrgzl I've updated my answer to show you a way to delete g's from a string.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.