C, Контакт с функциями аргумента переменной

Скажем, я хочу сделать что-то вроде этого

void my_printf(char *fmt,...) {
 char buf[big enough];
 sprintf(buf,fmt,...);  
}

То, каков надлежащий способ передать переменное количество аргументов непосредственно функции с, принимает аргументы переменной?

6
задан Mike 10 March 2010 в 22:16
поделиться

3 ответа

sprintf имеет форму va_list под названием vsprintf . Передайте ему va_list , который вы создаете локально, в качестве последнего аргумента.

void my_printf(char *fmt,...) {
 va_list ap;
 va_start(ap, fmt);

 char buf[big enough];
 vsprintf(buf,fmt,ap);

 va_end(ap);
}
9
ответ дан 10 December 2019 в 02:46
поделиться

Вы можете использовать функции стиля vsprintf, чтобы получить печать стиля printf для параметра переменной длины. Однако для этого нет никаких требований. Вы можете, если выберете написать свою функцию, чтобы она продолжала принимать параметры, пока не встретит нулевой указатель.

 va_list ap;
char *param;
va_start(ap,fmt);
param = va_arg(ap,char*);
while(param)
{
do something...
param = va_arg(ap,char*);
}

или вы можете указать количество параметров в качестве первого параметра вашей функции

void my_printf(int param_num,...)
{
 va_list ap;
char *param;
va_start(ap,fmt);
while(param_num)
{
do something...
param = va_arg(ap,char*);
param_num--;
}

}

Это действительно зависит от вас, возможности безграничны. Я думаю, что единственное реальное требование к эллипсам - это наличие хотя бы одного параметра перед эллипсами.

-1
ответ дан 10 December 2019 в 02:46
поделиться

Я не уверен, насколько полезным будет этот код, поскольку он написан на C ++, но он показывает, как с помощью специальной функции Win32 vsnprintf () проверить, что выделенный буфер достаточно велик, и, если нет, выделяет больший . И он возвращает std :: string, поэтому вам придется использовать malloc / realloc для обработки этого. Но какого черта:

string Format( const char * fmt, ... ) {
    const int BUFSIZE = 1024;
    int size = BUFSIZE, rv = -1;
    vector <char> buf( size );
    do {
        va_list valist;
        va_start(valist, fmt );
        // if vsnprintf() returns < 0, the buffer wasn't big enough
        // so increase buffer size and try again
        rv = _vsnprintf( &buf[0], size, fmt, valist );
        va_end( valist );
        size *= 2;
        buf.resize( size );
    }
    while( rv < 0 );
    return string( &buf[0] );
}
1
ответ дан 10 December 2019 в 02:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: