Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

переменное число аргуметнов

4 views
Skip to first unread message

Dmitry E. Oboukhov

unread,
Mar 18, 2008, 3:55:39 AM3/18/08
to
нужно написать функцию вида

int foo(int variable, ...)
{
// тут какие-то действия с variable
....

// а кончаться должно вызовом printf
return printf(...);
}

и вот printf'у должны передаваться все параметры которые идут в трех
точках
то есть некий враппер над printf мне нужен

чет я читаю man по stdarg и не пойму как это сделать

... Россия ныне ходит под Власовским флагом, позор!

Valera Kolesnik

unread,
Mar 18, 2008, 3:27:06 AM3/18/08
to
Hello Dmitry.

18 Mar 08 10:55, you wrote to all:

DO> нужно написать функцию вида

DO> int foo(int variable, ...)
DO> {
DO> // тут какие-то действия с variable
DO> ....

DO> // а кончаться должно вызовом printf
DO> return printf(...);
DO> }

DO> и вот printf'у должны передаваться все параметры которые идут в трех
DO> точках
DO> то есть некий враппер над printf мне нужен

DO> чет я читаю man по stdarg и не пойму как это сделать
блин, где-то ж видел именно пример с printf, как тебе и надо. а так страуструп
7.6:

void error(int severity ...) // "severity" followed by a zeroterminated list of
char*s
{
va_list ap ;
va_start(ap, severity); // arg startup

for(;;) {
char* p = va_arg(ap, char*);
if (p == 0) break;
cerr << p << ' ';
}
va_end(ap); // arg cleanup
cerr << '\n';
if (severity) exit (severity);
}

First, a va_list is defined and initialized by a call of va_start(). The macro
va_start takes the
name of the va_list and the name of the last formal argument as arguments. The
macro va_arg()
is used to pick the unnamed arguments in order. In each call, the programmer
must supply a type;
va_arg() assumes that an actual argument of that type has been passed, but it
typically has no way
of ensuring that. Before returning from a function in which va_start() has been
used, va_end()
must be called. The reason is that va_start() may modify the stack in such a
way that a return
cannot successfully be done; va_end() undoes any such modifications

Valera

Dmitry E. Oboukhov

unread,
Mar 18, 2008, 10:48:53 AM3/18/08
to
DO>> чет я читаю man по stdarg и не пойму как это сделать
VK> блин, где-то ж видел именно пример с printf, как тебе и надо. а так
VK> страуструп 7.6:

VK> void error(int severity ...) // "severity" followed by a zeroterminated
VK> list of char*s
VK> {
VK> va_list ap ;
VK> va_start(ap, severity); // arg startup

VK> for(;;) {
VK> char* p = va_arg(ap, char*);
VK> if (p == 0) break;
VK> cerr << p << ' ';
VK> }
VK> va_end(ap); // arg cleanup
VK> cerr << '\n';
VK> if (severity) exit (severity);
VK> }

тут в цикле вызывается << для cerr с очередным аргументом в виде
указателя на char.
а printf может принимать совсем разные аргументы
char, int, long, short, long long + указатели на все перечисленное
и соответственно все это разных размерностей.

то есть я так понимаю надо каким-то образом извлечь из стека первый
агрумент (его размер известен), а далее весь оставшийся стек сплавить
функции printf но как это сделать средствами C?


... Мы хлещем в жару портвейн! Мы не греем пива зимой!

Valera Kolesnik

unread,
Mar 18, 2008, 7:57:33 AM3/18/08
to
Hello Dmitry.

18 Mar 08 17:48, you wrote to me:

DO> тут в цикле вызывается << для cerr с очередным аргументом в виде
DO> указателя на char.
DO> а printf может принимать совсем разные аргументы
здесь показан алгоритм излечения следующего аргумента(ов):

va_start(ap, имя последнего известного) - инициализация
с помощь va_arg(ap, переменная любого типа, которую извлекаем) - делаем это
столько раз, сколько нужно (по какому-то заранее определённому признаку -
последний нолик, фиксированное количество, в каком-то из первых аргументов
формат и количество, ...)
va_end(ap) - корректно завершаем работу

DO> char, int, long, short, long long + указатели на все перечисленное
DO> и соответственно все это разных размерностей.
это в примере указатель на char. если тебе нужен другой тип - извлекай его

Valera

Alexey Dobronadezhdin

unread,
Mar 19, 2008, 4:13:49 AM3/19/08
to
DEO> ����� �������� ������� ����

DEO> int foo(int variable, ...)
DEO> {
DEO> // ��� �����-�� �������� � variable
DEO> ....

DEO> // � ��������� ������ ������� printf
DEO> return printf(...);
DEO> }

int foo(int variable, ...)
{
// ��� �����-�� �������� � variable
....

// � ��������� ������ ������� printf

va_list ap;
va_start(ap, variable);

char* format = "%s %d etc."; // ����� ��������� ������
int ret = vprintf(format, ap);

va_end(ap);

return ret;
}

�������� ���.

������� �������������

Nickita A Startcev

unread,
Mar 18, 2008, 2:28:44 PM3/18/08
to
Привет, Dmitry !


18 Mar 08 , 10:55 Dmitry E. Oboukhov писал к All:

DEO> int foo(int variable, ...)
DEO> {

DEO> // тут какие-то действия с variable
DEO> ....

DEO> // а кончаться должно вызовом printf
DEO> return printf(...);
DEO> }

DEO> и вот printf'у должны передаваться все параметры которые идут в трех
DEO> точках
DEO> то есть некий враппер над printf мне нужен

DEO> чет я читаю man по stdarg и не пойму как это сделать

man vprintf, vsprintf, va_start?

. С уважением, Hикита.
icq:240059686, lj-user:nicka_startcev
... Ка(ни)баллистические руны

Dmitry E. Oboukhov

unread,
Mar 19, 2008, 5:16:36 AM3/19/08
to
DO>> тут в цикле вызывается << для cerr с очередным аргументом в виде
DO>> указателя на char.
DO>> а printf может принимать совсем разные аргументы
VK> здесь показан алгоритм излечения следующего аргумента(ов):

VK> va_start(ap, имя последнего известного) - инициализация
VK> с помощь va_arg(ap, переменная любого типа, которую извлекаем) - делаем это
VK> столько раз, сколько нужно (по какому-то заранее определённому признаку -
VK> последний нолик, фиксированное количество, в каком-то из первых аргументов
VK> формат и количество, ...)
VK> va_end(ap) - корректно завершаем работу

DO>> char, int, long, short, long long + указатели на все перечисленное
DO>> и соответственно все это разных размерностей.

VK> это в примере указатель на char. если тебе нужен другой тип - извлекай его
так я ведь не знаю типа какой передадут такой и будет
не анализировать же строку format от printf заради этого?

... Деловой пиджачок, дорогие очки. Баксы в дипломате, но явились мы...

Dmitry E. Oboukhov

unread,
Mar 19, 2008, 5:19:25 AM3/19/08
to
DEO>> // а кончаться должно вызовом printf
DEO>> return printf(...);
DEO>> }

AD> int foo(int variable, ...)
AD> {
AD> // тут какие-то действия с variable
AD> ....

AD> // а кончаться должно вызовом printf

AD> va_list ap;
AD> va_start(ap, variable);

AD> char* format = "%s %d etc."; // здесь форматная строка
AD> int ret = vprintf(format, ap);
а здесь он в стек положит все оставшиеся аргументы?

за наводку на vprintf спасибо, пойду почитаю ман по нему

AD> va_end(ap);

AD> return ret;
AD> }

AD> Примерно так.

AD> Алексей Добронадеждин

... Я буду воевать только за красных!

Alexey Dobronadezhdin

unread,
Mar 19, 2008, 9:10:27 AM3/19/08
to
AD>> va_list ap;
AD>> va_start(ap, variable);

AD>> char* format = "%s %d etc."; // здесь форматная строка
AD>> int ret = vprintf(format, ap);

DEO> а здесь он в стек положит все оставшиеся аргументы?

В стек он положит адрес ap. А уже vprintf сумеет по значению в ap извлечь все
оставшиеся аргументы.

Алексей Добронадеждин

Nickita A Startcev

unread,
Mar 20, 2008, 2:30:12 AM3/20/08
to
Привет, Dmitry !


19 Mar 08 , 12:16 Dmitry E. Oboukhov писал к Valera Kolesnik:

DEO> так я ведь не знаю типа какой передадут такой и будет
DEO> не анализировать же строку format от printf заради этого?

man vprintf, vsprintf. Они на вход хотят ва_лист и сами разбирают.

. С уважением, Hикита.
icq:240059686, lj-user:nicka_startcev

... По сравнению с Шивой я почти инвалид

0 new messages