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.






Look very closely at your break; statement and ask why the inner loop never iterates.

– David C. Rankin
Sep 17 '18 at 2:27


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

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)