Удаление всех символов строки s1, встречающихся в s2 - C (СИ)
Формулировка задачи:
Здравствуйте! Пытаюсь решить задание из книги Кернигана и Ричи "Язык программирования Си".
Задание звучит так: "Напишите альтернативную версию ф-ции squeeze(s1,s2), которая бы удаляла из строки s1 все символы, встречающиеся в строке s2". Судя по контексту, речь идёт о массивах (а не о строковых константах)
Вот, что я написал:
Проблема в том, что если ввести во вторую строку более одного символа, то символ конца строки проглатывается, и в результирующем массиве оказываются
Листинг программы
- // Упражнение 2.4. Напишите squeeze(s1,s2), которая бы удаляла из строки s1 все символы, встречающиеся в строке s2.
- #include <stdio.h>
- #define STR_LIM 75 // макс. длина строки
- void squeeze(char s1[], char s2[]);
- void getline(char arr[], int str_length);
- int main()
- {
- char arr1[STR_LIM], arr2[STR_LIM];
- printf("\n Программа удаляет из строки №1 все символы, содержащиеся в строке №2.\n");
- printf("\n Введите строку№1...\n:>");
- getline(arr1, STR_LIM); // получаем первую строку
- printf("\n Теперь введите строку№2...\n:>");
- getline(arr2, STR_LIM); // получаем вторую строку
- // Подытоживая собранные данные...
- printf("\nВы ввели:%s и захотели удалить из неё символы: %s\n", arr1, arr2);
- squeeze(arr1, arr2);
- // Вывод результата
- printf("Получилась строка: %s\n", arr1);
- return 0;
- }
- //getline(arr[], limit): Получает из входного потока строку недлинее limit и сохраняет её в массиве-аргументе arr[]
- void getline(char arr[], int lim)
- {
- int x, i;
- i = 0;
- while ((x = getchar()) != '\n' && i < lim-2)
- arr[i++] = x;
- arr[i] = '\0';
- }
- //squeeze(s1,s2): Удаляет из строки s1 все символы. встречающиеся в строке s2.
- void squeeze(char s1[], char s2[])
- {
- int i, m, n;
- for (i = 0; s2[i] !='\0'; i++) // перебираем нежелательные символы из 2й строки
- for(m = n = 0; s1[m] != '\0'; m++)
- if (s1[m] != s2[i] && s1[m] != '\0')
- s1[n++] = s1[m];
- s1[n] = '\0';
- }
лишние символы
. Допустим, если ввести в 1ю строку "12345ggggg6789" и во вторую "gg", то получим "1234567896789
". Никак не могу сообразить, как с этим справиться, не разводя писанину... Если не трудно - подскажите плз!p.s.:
в задании говорилось про "альтернативную" версию. Так вот, в изначальной версии squeeze имела в качестве второго (удаляемого) аргумента простой символ. Можно сказать, что тело функции почти не изменилось, только обрело 1 лишнуюю переменную и внешний цикл, перебирающий все символы строки s2, которые не должны оставаться в s1. В связи с этим я думаю, что может надо было вообще по-другому подходить к решению?
Решение задачи: «Удаление всех символов строки s1, встречающихся в s2»
textual
Листинг программы
- #include <stdio.h>
- //функция удаляет из строки 1 все символы, которые есть в строке 2
- void squeeze(char s1[], char s2[])
- {
- int i, j, k, sovp;
- for(i=k=0; s1[i]!='\0'; i++) {
- sovp = 0;
- for(j=0; s2[j]!='\0'; j++) {
- if(s1[i]==s2[j])
- sovp = 1;
- }
- if(!sovp) //если совпадений не было
- s1[k++] = s1[i];
- }
- s1[k] = '\0';
- }
- int main()
- {
- char line1[] = "12345ggggg6789",
- line2[] = "gg";
- squeeze(line1, line2);
- printf("%s", line1);
- return 0;
- }
Объяснение кода листинга программы
- Включаем файл стандартного ввода/вывода
- Функция squeeze принимает два аргумента типа char: s1 и s2.
- Внутри функции объявляем четыре переменные: i, j, k и sovp.
- Переменная i используется для индексации строки s1, а переменная j - для индексации строки s2.
- Переменная k используется для индексации результирующей строки s1.
- Переменная sovp используется для проверки, был ли найден символ из строки s2 в строке s1.
- Используя два вложенных цикла, проходим по каждому символу строки s1.
- Для каждого символа проверяем, есть ли такой же символ в строке s2.
- Если символ найден, то переменной sovp присваивается значение 1.
- Если после прохода по всем символам строки s2 символ не был найден, то он добавляется в результирующую строку s1.
- После прохода по всем символам строки s1 добавляется символ '\0' для завершения строки.
- В функции main создаем две строки: line1 и line2.
- Строка line1 содержит
12345ggggg6789
, а строка line2 содержитgg
. - Вызываем функцию squeeze, передавая ей строку line1 и строку line2.
- После выполнения функции squeeze выводим на экран результат, используя функцию printf.
- Результатом будет строка
123456789
, так как все вхождения символаg
были удалены из строки line1. - Возвращаем 0, чтобы указать, что программа успешно завершилась.
- Если бы в функции main мы передали другие строки, например,
abracadabra
иab
, то результатом было быaracadabra
, так как все вхождения символаab
были удалены из исходной строки.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д