Срезание ненужных частей из строки

Мне нужно удалять из строки части, которые во время выполнения могут стать не нужными, я это делаю при помощи memmove.

Код работает, но вот он такой большой и длинный, что я думаю что я где-то намудрил с функцией которая удаляет ненужные части:

#define LIBKODIK_PARAMS_TYPES_START 7           /* Длина начала параматра в строке `type=` */
#define LIBKODIK_PARAMS_TYPES_NO_VALUE 42       /* Позиция в строке, если парамерт необходимо удалить полностью */
#define LIBKODIK_PARAMS_TYPES_MAX 12            /* Максимально возможное кол-во параметров для type=... */
#define LIBKODIK_PARAMS_PRINTF_LENGTH_STRING 3  /* Размер `%s,` */

void
libkodik_api_countries_param_types_remove_unusable_values(char *psz_value, uint8_t i_count) {
    size_t const s_strlen = strlen(psz_value);
    char buffer[s_strlen];
    (void) strcpy(buffer, psz_value);
    if (0 == i_count) { /* Кол-во параметров равно нулю? Просто срезает от и до */
        (void) memcpy
        (
            psz_value,
            &buffer[LIBKODIK_PARAMS_TYPES_NO_VALUE],
            s_strlen - LIBKODIK_PARAMS_TYPES_NO_VALUE + 1
        );
        return;
    }
    (void) memmove
    (
        &psz_value[LIBKODIK_PARAMS_TYPES_START],
        &buffer[LIBKODIK_PARAMS_TYPES_START] + (LIBKODIK_PARAMS_PRINTF_LENGTH_STRING * (LIBKODIK_PARAMS_TYPES_MAX - i_count)),
        s_strlen - (LIBKODIK_PARAMS_PRINTF_LENGTH_STRING * (LIBKODIK_PARAMS_TYPES_MAX - i_count) + 1)
    );
}

Этот тестовый код показывает что функция отрабатывает правильно, но может ее можно как-то улушить?

int main(void) {
    char buffer_flags[] = "types=%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s&year=%lu&translation_id=%lu&translation_type=%s&sort=%s";
    char buffer_flags2[] = "types=%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s&year=%lu&translation_id=%lu&translation_type=%s&sort=%s";
    uint8_t i_flags_count = 4;
    if (12 != i_flags_count) {
        libkodik_api_countries_param_types_remove_unusable_values(buffer_flags, i_flags_count);
    }
    printf("Changed:   %s\n",   buffer_flags);
    printf("Original:  %s\n",   "types=%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s&year=%lu&translation_id=%lu&translation_type=%s&sort=%s");
    i_flags_count = 0;
    if (12 != i_flags_count) {
        libkodik_api_countries_param_types_remove_unusable_values(buffer_flags2, i_flags_count);
    }
    printf("Changed2:  %s\n",   buffer_flags2);
    printf("Original2: %s\n",   "types=%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s&year=%lu&translation_id=%lu&translation_type=%s&sort=%s");
    return 0;
}
Changed:   types=%s,%s,%s,%s&year=%lu&translation_id=%lu&translation_type=%s&sort=%s
Original:  types=%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s&year=%lu&translation_id=%lu&translation_type=%s&sort=%s
Changed2:  year=%lu&translation_id=%lu&translation_type=%s&sort=%s
Original2: types=%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s&year=%lu&translation_id=%lu&translation_type=%s&sort=%s

Ответы (2 шт):

Автор решения: Zhihar

А зачем использовать конструкцию

&psz_value[LIBKODIK_PARAMS_TYPES_START]

чем плоха

psz_value + LIBKODIK_PARAMS_TYPES_START

Она даже лучше отражает суть

ВНИМАНИЕ:

char buffer[s_strlen];
(void) strcpy(buffer, psz_value);

я бы тут немного испугался - ведь строка должна заканчиваться \0, а у вас буфер на 1 байт меньше чем строка с \0

правильнее было бы написать

char buffer[s_strlen + 1];

иначе вы можете чего-то лишнего затереть (при условии, что размер строки кратен 4 к примеру)

→ Ссылка
Автор решения: eanmos

Что-то вы перемудрили. Требуемое поведение функции вами четко не определено, но насколько я понимаю, вот это должно работать:

void
remove_unusable_specifiers(char *s, unsigned int max_specifiers)
{
    char *begin = strlen("types=") + s;
    char *end = begin + strspn(begin, "%s,");

    if (max_specifiers == 0)  {
        memmove(s, end + 1, strlen(end) + 1);
        return;
    }

    memmove(begin + strlen("%s,") * max_specifiers - 1, end, strlen(end) + 1);
}

Основная проблема вашего кода — длинные и сложные имена сущностей (переменных и констант). Да, конечно, магические числа в коде — это плохо, но везде нужна золотая середина.

→ Ссылка