Функция с переменным количеством параметров в Си

Необходимо «конвертировать» код программы из С++ в С.

Условие задачи:

Написать функцию с переменным количеством параметров. Первым параметром передавать количество последующих параметров. Функция принимает символы. Сформировать строку из переданных символов. Если очередной символ - '#', то предыдущий символ в строку не включать (например, для "asd# 89yui##" результатом будет "as 89y") - решётки тоже не включаются в строку.

Код:

    #include <string>
    #include <iostream>
    using namespace std;
    template<typename... Args>
    string fn(Args... args)
    {
        auto seq = initializer_list<char>({ args... });
        string str;
        for (auto ch : seq)
        {
            if (ch == '#' && !str.empty()) str.pop_back();
            else str += ch;
        }
        return str;
    }
    
    int main() 
    {
        auto str = fn('a', 's', 'd', '#', ' ', '8', '9', 'y', 'u', 'i', '#', '#');
        cout << str << '\n';
        system("pause > nul");
    }

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

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

Написать функцию с переменным количеством параметров.

Процитирую документацию:

void va_start(va_list argptr, last_parm)
void va_end(va_list argptr)
void va_arg(va_list argptr, type)

Прототип в:

stdarg.h

Описание:

Макросы va_arg(), va_start() и va_end() используются совместно для того, чтобы осуществить передачу функции переменного числа параметров. Наиболее общеупотребительным примером ис­пользования функции с переменным числом параметров служит printr(). Тип va_list определен в файле stdarg.h.

Общая процедура создания функции, которая имеет переменное число аргументов, заключает­ся в следующем: функция должна иметь один или более известных параметров. Эти известные параметры следуют перед списком переменных параметров. Самый правый известный параметр называется last_parm. Имя last_parm используется в качестве второго параметра в вызове va_start(). Прежде чем осуществлять доступ к какому-либо из переменных параметров, должен быть иници­ализирован указатель argptr, для чего используется вызов va_start(). После этого параметры воз­вращаются с помощью вызова функции va_arg() с параметром type, являющимся типом следующе­го параметра. Наконец, после того, как все параметры прочитаны, перед тем как выйти из функции, необходимо вызвать функцию va_end(), что гарантирует правильное восстановление стека. Если функция va_end() не вызвана, то возникает аварийная ситуация.

Пример:

Следующая программа использует функцию sum_series() для возврата суммы последовательности чисел. Первый аргумент содержит счетчик числа аргументов, которые будут переданы функции.

В данном примере суммируются первые пять элементов последовательности:

(1/2)+(1/4)+(1/8)+(1/16) ...

Программа выведет результат «0.968750».

/* пример аргумента переменной длины - сумма последовательности */
#include <stdio.h>
#include <stdarg.h>
double sum_series(int, ...);

int main(void)
{
    double d;
    d = sum_series(5, 0.5, 0.25, 0.125, 0.0625, 0.03125);
    printf("Sum of series is %f\n",d);
    return 0;
}

double sum_series(int num, ...)
{
    double sum = 0.0, t;
    va_list argptr;

    /* инициализация argptr */
    va_start (argptr, num);

    /* сумма последовательности */
    for(; num; num—) {
        t = va_arg(argptr,double);
        sum += t;
    }

    /* завершение */
    va_end(argptr);
    return sum;
}
→ Ссылка