Removing array of occurrences from string in C
Removing array of occurrences from string in C
I'm having looping issues with my code. I have a method that takes in two char arrays (phrase, characters). The characters array holds characters that must be read individually and compared to the phrase. If it matches, every occurrence of the character will be removed from the phrase.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//This method has two parameters: (str, c)
//It will remove all occurences of var 'c'
//inside of 'str'
char * rmstr(char * c, char * str)
//Declare counters and pointers
int stemp = 0;
int ctemp = 0;
char *p = str;
char *d = c;
//Retrieve str count
while(str[stemp] != '')
stemp++;
//Retrieve c count
while(c[ctemp] != '')
ctemp++;
//Output information
printf("String Count: %dn",stemp);
printf("Character Count: %dn",ctemp);
//Iterate through arrays
for (int i = 0; i != stemp; i++)
for (int j = 0; j != ctemp; j++)
if (c[j] != str[i])
*p++ = str[i];
break;
printf("%sn",str);
*p = 0;
return str;
int main()
char c[256] = "ema";
char input[256] = "Great message!";
char *result = rmstr(c, input);
printf("%s", result);
return 0;
In this case, the input would be "Great Message!" and the character I'd like to remove all occurrences of the characters: e, m, a (As specified in main).
Using the code as it is above, the output is as follows:
Grat mssag!
It is only looping through 1 iteration and removing 'e'. I would like it to loop through 'm' and 'a' as well.
break;
I see that it's stopping the next iteration. I feel like im missing something critical as the output comes out as "GGGGG....".
– Nascosto
Sep 17 '18 at 2:43
It seems to me what you are trying to get as output is
"Grt ssg!"
, but that is not clear from your question. If that is the case, then I would reorder the loops to loop over c
then over str
removing all occurrences of the current char in c
from str
.– David C. Rankin
Sep 17 '18 at 2:46
"Grt ssg!"
c
str
c
str
I've done what you described above. Do I need any other arrays or pointers? Or should this be straightforward while im inside of the loop?
– Nascosto
Sep 17 '18 at 3:00
1 Answer
1
After you fix your break;
that was causing your inner loop to exit, it may make sense to reorder your loops and loop over the chars to remove while checking against the characters in str
. This is more of a convenience allowing you to shuffle each character down by one in str
if it matches a character is c
. If you are using the functions in string.h
like memmove
to move characters down, it doesn't really matter.
break;
str
str
c
string.h
memmove
A simple implementation using only pointers to manually work through str
removing all chars in c
could look something like the following:
str
c
#include <stdio.h>
char *rmstr (char *str, const char *chars)
const char *c = chars; /* set pointer to beginning of chars */
while (*c) /* loop over all chars with c */
char *p = str; /* set pointer to str */
while (*p) /* loop over each char in str */
if (*p == *c) /* if char in str should be removed */
char *sp = p, /* set start pointer at p */
*ep = p + 1; /* set end pointer at p + 1 */
do
*sp++ = *ep; /* copy end to start to end of str */
while (*ep++); /* (nul-char copied on last iteration) */
p++; /* advance to next char in str */
c++; /* advance to next char in chars */
return str; /* return modified str */
int main (void)
char c = "ema";
char input = "Great message!";
printf ("original: %sn", input);
printf ("modified: %sn", rmstr (input, c));
return 0;
(there are many ways to do this -- how is largely up to you. whether you use pointers as above, or get the lengths and use string-indexes is also a matter of choice)
Example Use/Output
$ ./bin/rmcharsinstr
original: Great message!
modified: Grt ssg!
If you did want to use memmove
(to address the overlapping nature of the source and destination) to move the remaining characters in str
down by one each time the character in str
matches a character in c
, you could leave the loops in your original order, e.g.
memmove
str
str
c
#include <string.h>
char *rmstr (char *str, const char *chars)
char *p = str; /* set pointer to str */
while (*p) /* loop over each char in str */
const char *c = chars; /* set pointer to beginning of chars */
while (*c) /* loop over all chars with c */
while (*c == *p) /* while the character matches */
memmove (p, p + 1, strlen (p)); /* shuffle down by 1 */
c = chars; /* reset c = chars to check next */
c++; /* advance to next char in chars */
p++; /* advance to next char in str */
return str; /* return modified str */
(make sure you understand why you must reset c = chars;
in this case)
c = chars;
Finally, if you really wanted the shorthand way of doing it, you could use strpbrk
and memmove
and reduce your function to:
strpbrk
memmove
#include <string.h>
char *rmstr (char *str, const char *chars)
/* simply loop using strpbrk removing the character found */
for (char *p = strpbrk (str, chars); p; p = strpbrk (str, chars))
memmove (p, p+1, strlen(p));
return str; /* return modified str */
(there is always more than one way to skin-the-cat in C)
The output is the same. Look things over here and let me know if you have further questions.
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy
Look very closely at your
break;
statement and ask why the inner loop never iterates.– David C. Rankin
Sep 17 '18 at 2:27