Reputation: 11
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
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:
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 char
0 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.
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
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
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
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