Как удалить все вхождения данного символа из строки в C? - PullRequest
19 голосов
/ 27 марта 2012

Я пытаюсь удалить символ из строки в C. Проблема, с которой я столкнулся в своем коде, заключается в том, что он удаляет первый экземпляр символа из строки, но также стирает все после этого символа в строке. Например, удаление «l» из «hello» выводит «he» вместо «heo»

int i;
char str1[30] = "Hello", *ptr1, c = 'l';
ptr1 = str1;
for (i=0; i<strlen(str1); i++)
{
    if (*ptr1 == c) *ptr1 = 0;
    printf("%c\n", *ptr1);
    ptr1++;
}

Мне нужно использовать указатели для этого, и я хотел бы сделать это как можно более простым, поскольку я новичок в C. Спасибо

Ответы [ 7 ]

25 голосов
/ 27 марта 2012

Вы можете сделать это следующим образом:

void remove_all_chars(char* str, char c) {
    char *pr = str, *pw = str;
    while (*pr) {
        *pw = *pr++;
        pw += (*pw != c);
    }
    *pw = '\0';
}

int main() {
    char str[] = "llHello, world!ll";
    remove_all_chars(str, 'l');
    printf("'%s'\n", str);
    return 0;
}

Идея состоит в том, чтобы сохранить отдельные указатели чтения и записи (pr для чтения и pw для записи), всегда перемещать указатель чтения,и продвигать указатель записи только тогда, когда он не указывает на данный символ.

4 голосов
/ 27 марта 2012

Если вы удалите символы на месте, вам придется сдвигать оставшуюся часть строки на одну позицию влево каждый раз, когда вы удаляете символ, это не очень эффективно. Лучше всего иметь второй массив, который принимает отфильтрованную строку. Например, вы можете изменить свой код следующим образом.

int i;
char str1[30] = "Hello", *ptr1, c = 'l';
char str2[30] = {0}, *ptr2;
ptr1 = str1;
ptr2 = str2;
for (i=0; i<strlen(str1); i++)
{
    if (*ptr1 != c) *ptr2++=*ptr1;
    ptr1++;
}
printf("%s\n", str2);
2 голосов
/ 27 марта 2012
char str1[30] = "Hello", *prt1, c = 'l';
char str2[30], *prt2;
prt1 = str1;
prt2 = str2;
while(*prt1 != 0)
{
    if(*prt1 != c)
    {
         *prt2 = *prt1;
         prt2++;  
    }
    prt1++;
}
*prt2 = '\0';
1 голос
/ 03 мая 2014

Я знаю, что это тип дублирующего ответа, но этот код является версией функции для решения проблемы. Я думал, что, поскольку спрашивающий был новичком, он мог бы многому научиться из разложенной версии проблемы.

int del_x_char(char *p, int x)
{
    char *q;
    x=first_occurance(p, 'i')/*you can replace any character that you want delete with 'i'*/
    q=p+x;
    while(*q=*(q+1))
        q++;
    *q='\0';
    return 0;
}
int first_occurance(char *q, char phar)
{
    int i=0;
    while(*q)
    {   
        if(*q++==phar)
            return i;
        i++;
    }
    return -1;
}
1 голос
/ 27 марта 2012

Проблема в том, что когда вы сталкиваетесь с первым символом, который соответствует c, вы тут же вставляете нулевой символ. Это означает, что вы по существу обрезаете остальную часть строки.

Что вам нужно сделать, это когда вы найдете соответствующий символ, переместите следующие символы обратно на одну позицию. Затем вам нужно вставить нулевой символ в самом конце, в зависимости от того, сколько символов вы удалили.

0 голосов
/ 27 марта 2012

просто измените

if (*ptr1 == c) *ptr1 = 0;

на

if (*ptr1 == c) continue;

, как сказал @ouah, он прерывается на первый символ NULL ..

0 голосов
/ 27 марта 2012

C определяет строку как "непрерывная последовательность символов, оканчивающаяся и включающая первый нулевой символ "

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...