Как удалить все символы из строки, которые находятся в другой строке?

#c #string #c-strings

#c #строка #c-строки

Вопрос:

Мне нужно удалить все буквы, из s1 которых есть s2 . Я не могу понять, что не так с моим кодом:

 #include <stdio.h>
#include <stdlib.h>

void squeeze(char s1[], char s2[])
{
    int i,j;
    i=j=0;

    for(i; s2[i]!=''; i  ) {
        for (j; s1[j] != ''; j  ) {
            if (s1[j] == s2[i]) {
                s1[j] = s1[j   1];
                --j;
            }
        }
    }
}

int main()
{
    char w1[] = "abcde";
    char w2[] = "fghaj";
    squeeze(w1,w2);
    puts(w1);
    return 0;
}
 

но вывод:

 abcde
 

Что я должен исправить?

Комментарии:

1. Вы пробовали пошагово выполнять код оператор за оператором в отладчике? О чем это вам говорит?

2. я новичок, поэтому мне это ничего не говорит, более того, я никогда раньше не использовал debugger

3. Тогда используйте это как идеальное время, чтобы узнать , как использовать отладчик. Возможность использования отладчика действительно обязательна, если вы хотите выполнять какое-либо программирование.

4. спасибо, я это увижу

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

Ответ №1:

Для начала переменная j не сбрасывается 0 во внутренний цикл для каждой итерации внешнего цикла.

Во-вторых, если символ должен быть удален, то все символы после него не перемещаются влево на одну позицию. Вы просто заменяете удаленный символ следующим символом в строке.

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

 #include <stdio.h>
#include <string.h>

char * squeeze( char s1[], const char s2[] )
{
    for ( char *p = s1, *q = s1; *q;   p )
    {
        if ( !*p || !strchr( s2, *p ) )
        {
            if ( q != p )
            {
                *q = *p;
            }
            if ( *p )   q;
        }
    }
    
    return s1;
}

int main( void )
{
    char w1[] = "abcde";
    char w2[] = "fghaj";
    
    puts( squeeze( w1, w2 ) );

    return 0;
} 
 

Вывод программы

 bcde
 

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

 #include <stdio.h>

char * squeeze( char s1[], const char s2[] )
{
    for ( size_t i = 0, j = 0; s1[j] != '';   i )
    {
        size_t k = 0;
        
        while ( s2[k] != '' amp;amp; s2[k] != s1[i] )   k;
        
        if ( s2[k] == '' )
        {
            if ( j != i )
            {
                s1[j] = s1[i];
            }
            if ( s1[i] != '' )   j;
        }
    }
    
    return s1;
}

int main( void )
{
    char w1[] = "abcde";
    char w2[] = "fghaj";
    
    puts( squeeze( w1, w2 ) );

    return 0;
}
 

Вывод программы такой же, как показано для предыдущей демонстрационной программы

 bcde
 

Комментарии:

1. спасибо, но я должен сделать это без указателей / индикаторов

2. @HGH Что такое индикатор?

3. я имею в виду ‘ * » просто не знаю, как сказать это по-английски, может быть, указатель? индекс?

Ответ №2:

Две проблемы в squeeze :

  1. Вам нужно повторно инициализировать j до нуля при каждом проходе через цикл.
  2. Вам нужно скопировать всю оставшуюся часть строки на один символ влево, а не только символ, следующий за тем, который вы хотите удалить.

Я предлагаю вам переписать squeeze как:

 void squeeze(char s1[], char s2[])
{
    int i,j;
    i=j=0;

    for( ; s2[i]!=''; i  ) {
        for (j = 0; s1[j] != ''; j  ) {
            if (s1[j] == s2[i]) {
              strcpy(s1 j, s1 j 1);
              --j;
            }
        }
    }
}
 

Комментарии:

1. хорошо, спасибо, но как это сделать без ‘strcpt’?

2. Напишите другой цикл, чтобы делать то, что strcpy делает.

3. я пытаюсь: void squeeze(char s1[], char s2[]) { int i, j,k; for(i= 0; s2[i]!=»; i ) { for (j = 0; s1[j] != »; j ) { if (s1[j] == s2[i]) { for(k= j; k != »; k ) { s1[k] = s1[k 1]; } } } } }

4. @Bob Jarvis — Восстановить Monica Предоставленный код с strcpy имеет неопределенное поведение.

Ответ №3:

Я вижу здесь проблему, ваш код по какой-то причине не вводит этот оператор :

  if (s1[j] == s2[i]) {
            s1[j] = s1[j   1];
            --j;
        }
 

ваш вопрос может быть почему? поскольку для i и j не задано значение 0, попробуйте распечатать их, и вы увидите, что j переместится на 4, но i навсегда останется равным 0
, поэтому для начала вы можете исправить это, выполнив это

 for(i=0; s2[i]!=''; i  ) {
for (j=0; s1[j] != ''; j  ) {
 

затем вы не скопировали всю строку и переместили ее на один шаг назад, чтобы переписать найденный символ, вы переместили только один символ и оставили его пустым
Exemple

 input : abcde
output :b_cde
 

чтобы исправить это, у вас есть два метода :
используйте strcpy , чтобы переместить код на один шаг назад

 for(i=0; s2[i]!=''; i  ) {
    for (j=0; s1[j] != ''; j  ) {
        if (s1[j] == s2[i]){
            strcpy(s1 j, s1 j 1);
            --j;
        }


    }
 

или вы можете просто создать ту же функцию, используя букле для

 for(i=0; s2[i]!=''; i  ) {
    for (j=0; s1[j] != ''; j  ) {
        if (s1[j] == s2[i]){
            for (k=j;s1[k] != '';k  )
            s1[k] = s1[k   1];
            --j;
        }


    }
 

Комментарии:

1. спасибо, но как это сделать без ‘strcpy’? я знаю, что я должен использовать третий цикл, но я не знаю как…

2. @HGH Я не уверен, видите ли вы последнюю часть, попробуйте обновить страницу, поскольку я уже писал о том, как использовать ту же функцию strcpy, используя для букле

3. да, страница не обновлялась, теперь я вижу, большое спасибо!

4. @HGH я рад, что мне удалось вам помочь. Не сдавайтесь и попытайтесь использовать больше примеров для достижения вашего решения

5. @HGH это работает на моей стороне, я попытался изменить строку. Пожалуйста, предоставьте больше информации, чтобы отследить проблему

Ответ №4:

      #include <stdio.h>
     #include <string.h>

     int rem_str(char * porgstr, char * pdel) {
         if (!porgstr || !pdel) {
             return 0;
         }
         int i = 0;
         int j = 0;    
         char tmp[256] = {0};
         int len = strlen(pdel);
         for (i = 0; i < len; i  ) {
            tmp[pdel[i]]  ;
         }
         len = strlen(porgstr);
         for (i = 0, j=0; i < len; i  ) {
            if(tmp[porgstr[i]] == 0) {
                porgstr[j] = porgstr[i];
                j  ;
            }
         }
         porgstr[j] = 0;
         return 0;
     }
     int main () {
         char * input1 = strdup("origional string passed to program");
         char * input2 = strdup("sdel");

         printf("Input before del : %sn", input1);
         rem_str(input1, input2);
         printf("String after del : %sn", input1);

         return 0;
     }
 

Вывод:

       ./a.out 
     Input before del : origional string passed to program
     string after del : origiona tring pa to program