Удаление всех символов строки s1, встречающихся в s2 - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Здравствуйте! Пытаюсь решить задание из книги Кернигана и Ричи "Язык программирования Си". Задание звучит так: "Напишите альтернативную версию ф-ции squeeze(s1,s2), которая бы удаляла из строки s1 все символы, встречающиеся в строке s2". Судя по контексту, речь идёт о массивах (а не о строковых константах) Вот, что я написал:
Листинг программы
  1. // Упражнение 2.4. Напишите squeeze(s1,s2), которая бы удаляла из строки s1 все символы, встречающиеся в строке s2.
  2. #include <stdio.h>
  3. #define STR_LIM 75 // макс. длина строки
  4. void squeeze(char s1[], char s2[]);
  5. void getline(char arr[], int str_length);
  6. int main()
  7. {
  8. char arr1[STR_LIM], arr2[STR_LIM];
  9. printf("\n Программа удаляет из строки №1 все символы, содержащиеся в строке №2.\n");
  10. printf("\n Введите строку№1...\n:>");
  11. getline(arr1, STR_LIM); // получаем первую строку
  12. printf("\n Теперь введите строку№2...\n:>");
  13. getline(arr2, STR_LIM); // получаем вторую строку
  14. // Подытоживая собранные данные...
  15. printf("\nВы ввели:%s и захотели удалить из неё символы: %s\n", arr1, arr2);
  16. squeeze(arr1, arr2);
  17. // Вывод результата
  18. printf("Получилась строка: %s\n", arr1);
  19. return 0;
  20. }
  21. //getline(arr[], limit): Получает из входного потока строку недлинее limit и сохраняет её в массиве-аргументе arr[]
  22. void getline(char arr[], int lim)
  23. {
  24. int x, i;
  25. i = 0;
  26. while ((x = getchar()) != '\n' && i < lim-2)
  27. arr[i++] = x;
  28. arr[i] = '\0';
  29. }
  30. //squeeze(s1,s2): Удаляет из строки s1 все символы. встречающиеся в строке s2.
  31. void squeeze(char s1[], char s2[])
  32. {
  33. int i, m, n;
  34. for (i = 0; s2[i] !='\0'; i++) // перебираем нежелательные символы из 2й строки
  35. for(m = n = 0; s1[m] != '\0'; m++)
  36. if (s1[m] != s2[i] && s1[m] != '\0')
  37. s1[n++] = s1[m];
  38. s1[n] = '\0';
  39.  
  40. }
Проблема в том, что если ввести во вторую строку более одного символа, то символ конца строки проглатывается, и в результирующем массиве оказываются

лишние символы

. Допустим, если ввести в 1ю строку "12345ggggg6789" и во вторую "gg", то получим "123456789

6789

". Никак не могу сообразить, как с этим справиться, не разводя писанину... Если не трудно - подскажите плз!

p.s.:

в задании говорилось про "альтернативную" версию. Так вот, в изначальной версии squeeze имела в качестве второго (удаляемого) аргумента простой символ. Можно сказать, что тело функции почти не изменилось, только обрело 1 лишнуюю переменную и внешний цикл, перебирающий все символы строки s2, которые не должны оставаться в s1. В связи с этим я думаю, что может надо было вообще по-другому подходить к решению?

Решение задачи: «Удаление всех символов строки s1, встречающихся в s2»

textual
Листинг программы
  1. #include <stdio.h>
  2.  
  3. //функция удаляет из строки 1 все символы, которые есть в строке 2
  4. void squeeze(char s1[], char s2[])
  5. {
  6.      int i, j, k, sovp;
  7.      
  8.      for(i=k=0; s1[i]!='\0'; i++) {
  9.         sovp = 0;
  10.         for(j=0; s2[j]!='\0'; j++) {
  11.            if(s1[i]==s2[j])
  12.               sovp = 1;
  13.         }
  14.         if(!sovp) //если совпадений не было
  15.            s1[k++] = s1[i];
  16.      }
  17.      s1[k] = '\0';
  18. }
  19.  
  20. int main()
  21. {
  22.     char line1[] = "12345ggggg6789",
  23.          line2[] = "gg";
  24.    
  25.     squeeze(line1, line2);
  26.     printf("%s", line1);
  27.     return 0;
  28. }

Объяснение кода листинга программы

  1. Включаем файл стандартного ввода/вывода
  2. Функция squeeze принимает два аргумента типа char: s1 и s2.
  3. Внутри функции объявляем четыре переменные: i, j, k и sovp.
  4. Переменная i используется для индексации строки s1, а переменная j - для индексации строки s2.
  5. Переменная k используется для индексации результирующей строки s1.
  6. Переменная sovp используется для проверки, был ли найден символ из строки s2 в строке s1.
  7. Используя два вложенных цикла, проходим по каждому символу строки s1.
  8. Для каждого символа проверяем, есть ли такой же символ в строке s2.
  9. Если символ найден, то переменной sovp присваивается значение 1.
  10. Если после прохода по всем символам строки s2 символ не был найден, то он добавляется в результирующую строку s1.
  11. После прохода по всем символам строки s1 добавляется символ '\0' для завершения строки.
  12. В функции main создаем две строки: line1 и line2.
  13. Строка line1 содержит 12345ggggg6789, а строка line2 содержит gg.
  14. Вызываем функцию squeeze, передавая ей строку line1 и строку line2.
  15. После выполнения функции squeeze выводим на экран результат, используя функцию printf.
  16. Результатом будет строка 123456789, так как все вхождения символа g были удалены из строки line1.
  17. Возвращаем 0, чтобы указать, что программа успешно завершилась.
  18. Если бы в функции main мы передали другие строки, например, abracadabra и ab, то результатом было бы aracadabra, так как все вхождения символа ab были удалены из исходной строки.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

11   голосов , оценка 4.364 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы