Перед каждым вхождением символа C в строку S вставить строку S0 - C (СИ)

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

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

Гайз, прошу вашей помощи. Пытаюсь решить следующую задачу: "Дан символ C и строки S, S0. Перед каждым вхождением символа C в строку S вставить строку S0." Знаю, что ее можно и наверное будет проще решить использую различные функции библиотеки string.h, но хочу решить ее методом, продемонстрированным ниже, если это возможно. Помощь нужна в поиске ошибки, т.к. программа работает неисправно. Код программы:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <string.h>
 
int main()
{
    setlocale (2, "RUSSIAN");
 
    int i, j, k;
    char *S, S0[256], C;
 
    S=(char *)malloc(256*sizeof(char));
 
    printf("Программа вставляет строку S0 перед каждым вхождением символа C в строку S.\n\n");
    printf("Введите строку S: ");
    gets(S);
    printf("Введите строку S_0: ");
    gets(S0);
    printf("Введите символ С: ");
    C=getchar();
 
    for (i=0; i<strlen(S); i++) /// Бегу по всем элементам строки S слева направо
        if (*(S+i)==C) { /// Если нашел в строке элемент С, то...
            S=realloc(S, (strlen(S)+strlen(S0)+1)*sizeof(char)); /// Увеличиваю память под строку на длину S0
            for (j=strlen(S); j>=i; j--) /// Совершаю сдвиг элементов строки S (включая символ конца строки) справа налево
               *(S+j+strlen(S0))=*(S+j); /// на число равное длине строки S0
            for (j=i, k=0; k<strlen(S0); j++, k++) /// Вставляю все элементы строки S0 в освободившееся из-за сдвига место в строке S,
               *(S+j)=S0[k]; /// кроме символа конца строки S0
        }
 
    puts(S);
 
    return 0;
}
Выяснил, что загвоздка в этой части программы, так как цикл выполняется бесконечно:
for (j=strlen(S); j>=i; j--) /// Совершаю сдвиг элементов строки S (включая символ конца строки) справа налево
   *(S+j+strlen(S0))=*(S+j); /// на число равное длине строки S0
НЕ МОГУ ПОНЯТЬ, В ЧЕМ БЕДА!!1 Это ведь связано с дурацким символом конца строки? И как это исправить? Заранее благодарю!

Решение задачи: «Перед каждым вхождением символа C в строку S вставить строку S0»

textual
Листинг программы
#include <stdio.h>
#include <string.h>
#include <malloc.h>
 
int str_insert(char** s, char c, const char* s0){
    size_t l, n, m;
    char*  t, *p = *s;
 
    m = strlen(s0);
    l = 0;
    while((p = strchr(p, c)) != NULL){
        l += m;
        ++p;
    }
    if(! l || ! *s0)
        return 0;
 
    n = strlen(*s) + 1;
    p = (char*)realloc(*s, (n + l) * sizeof(char));
    if(p == NULL)
        return 0;
    
    t = *s = p;
    while((p = strchr(p, c)) != NULL){
        memmove(p + m, p, (n - (size_t)(p - t)) * sizeof(char));
        strncpy(p, s0, m);
        p += m + 1;
        n += m;
    }
    return 1;
}
 
 
int main(void){
    char* s = strdup("X, X, (X), X, {X}XX");
    if(s == NULL)
        return 1;
 
    puts(s);
    if(str_insert(&s, 'X', "Direct"))
        puts(s);
 
    //...
    free(s);
    return 0;
}

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

  1. Включаем необходимые заголовочные файлы для работы со строками и памятью
  2. Определяем функцию str_insert, которая принимает указатель на строку, символ, который необходимо вставить и строку, которую необходимо вставить
  3. Инициализируем переменные: m - длина строки, которую необходимо вставить, l - длина вставленной строки, t - указатель на текущий символ строки, p - указатель на текущий символ строки
  4. Используем функцию strlen для определения длины строки s0
  5. В цикле while ищем все вхождения символа c в строке s. Если символ найден, увеличиваем значение l на длину строки s0 и сдвигаем указатель p на следующую позицию в строке s
  6. Проверяем, были ли вхождения символа c и строки s0. Если нет, возвращаем 0. Иначе, продолжаем выполнение функции
  7. Вычисляем новую длину строки s с учетом вставленных строк s0
  8. Реализуем функцию realloc для выделения памяти под новую длину строки s. Если память не может быть выделена, возвращаем 0. Иначе, обновляем указатель на начало строки s и на текущую позицию в строке s
  9. Копируем строку s в новую выделенную память
  10. В цикле while вставляем строку s0 в нужное место в строке s. Для этого перемещаем символы, начиная с текущей позиции в строке s, на позицию, равную текущей позиции плюс длина строки s0. Затем копируем строку s0 в освободившуюся память
  11. Увеличиваем длину строки s на длину вставленной строки s0
  12. Возвращаем 1, если все операции выполнены успешно, и 0 в противном случае
  13. В функции main создаем строку s и выводим ее на экран
  14. Вызываем функцию str_insert для вставки строки Direct перед каждым вхождением символа 'X' в строке s. Выводим измененную строку s на экран
  15. Выполняем дополнительные действия, если необходимо
  16. Освобождаем память, выделенную под строку s
  17. Возвращаем 0, если все операции выполнены успешно, и 1 в противном случае

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

11   голосов , оценка 4 из 5
Похожие ответы