C, Работа с переменными аргументами - PullRequest
6 голосов
/ 11 марта 2010

Допустим, я хочу сделать что-то вроде этого

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

Как правильно передать переменное число аргументов непосредственно в функцию с переменными аргументами?

Ответы [ 3 ]

9 голосов
/ 11 марта 2010

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);
}
1 голос
/ 11 марта 2010

Я не уверен, насколько полезным будет этот код, так как это 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] );
}
0 голосов
/ 11 марта 2010

Вы можете использовать функции стиля 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--;
}

}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...