После того, как вы исправите break;
, из-за которого выходил внутренний цикл, может иметь смысл переупорядочить ваши циклы и удалить циклы по символам, проверяя символы в str
.Это более удобно, позволяя вам перетасовать каждый символ на единицу в str
, если он соответствует символу c
.Если вы используете функции из string.h
, такие как memmove
, для перемещения символов вниз, это не имеет значения.
Простая реализация, использующая только указатели для ручной работы через 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: %s\n", input);
printf ("modified: %s\n", rmstr (input, c));
return 0;
}
(есть много способов сделать это - насколько это зависит от вас. Используете ли вы указатели, как указано выше, или получаете длины и используете строку-индексы также являются предметом выбора)
Пример использования / вывода
$ ./bin/rmcharsinstr
original: Great message!
modified: Grt ssg!
Если вы действительно хотите использовать 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 */
}
(убедитесь, что вы понимаете, почему вы должны сбросить c = chars;
в этом случае)
Наконец, если вы действительно хотите краткий способ сделать это, вы можете использовать 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 */
}
(всегда существует более одного пути к skin-the-cat в C)
Вывод один и тот же.Посмотрите здесь и дайте мне знать, если у вас есть дополнительные вопросы.