Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Архив форумов ЦИТФорума
Море(!) вопросов - Море(!) ответов
 
 FAQFAQ   ПоискПоиск   ПользователиПользователи   ГруппыГруппы   РегистрацияРегистрация 
 ПрофильПрофиль   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 
Как правильно задавать вопросы

Функции с переменным количеством аргументов в C++

 
Перейти:  
Этот форум закрыт, вы не можете писать новые сообщения и редактировать старые.   Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.    Список форумов Архив форумов ЦИТФорума -> Программирование
Предыдущая тема :: Следующая тема  
Автор Сообщение
Алексей Инкин



Зарегистрирован: 19.09.2004
Сообщения: 32
Откуда: Россия, Нижний Новгород

СообщениеДобавлено: Вс Мар 20 2005 18:58    Заголовок сообщения: Функции с переменным количеством аргументов в C++ Ответить с цитатой

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

va_start(lstArguments, strPrintfPattern);
vprintf(strPrintfPattern, lstArguments);
va_end(lstArguments);

Это работает замечательно. Но что если мне нужно перед этими переменными аргументами вставить один свой? Строку с шаблоном модифицировать легко, а вот как пропихнуть дополнительный аргумент в список? Т.е. мне нужно, например, чтобы при вызове

fn("%i", 123);

моя функция вызывала

printf("%s%i", "My Additional String", 123);

printf я привёл для простоты, на самом деле я вызываю syslog / vsyslog, которые тоже работают с переменным количеством аргументов. Поэтому вариант писать в два захода не подходит. Вручную перебирать все аргументы тоже не хочется.
Спасибо, если кто знает, что делать... Smile
_________________
puts("hit");
printf("uck");
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
genok



Зарегистрирован: 01.02.2005
Сообщения: 9

СообщениеДобавлено: Ср Мар 23 2005 05:31    Заголовок сообщения: Ответить с цитатой

Почему бы в начале функции не обрабатывать те строковые параметры, которые надо вставлять, и просто делать составную строку из нужных спецификаторов формата? Это же можно сделать при одном спецификаторе с помощью switch или для варианта с несколькими с помощью условных операторов if then else... Cool
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail
Алексей Инкин



Зарегистрирован: 19.09.2004
Сообщения: 32
Откуда: Россия, Нижний Новгород

СообщениеДобавлено: Ср Мар 23 2005 06:16    Заголовок сообщения: Ответить с цитатой

Если бы проблема заключалась в переделывании форматной строки, то я бы наверное не захламлял этот форум Smile
Меня интересует следующее: хочу именно физически пропихнуть в функцию несколько дополнительных параметров, а не просто заявить об этом в строке формата. Функция существует в двух вариантах: printf(const char*, ...) и vprintf(const char*, va_list), а мне в идеале нужно что-то вроде fn(const char*, ..., va_list).
Вот появилась одна идея, как это сделать с ассемблерными вставами: вручную пропихивать параметры в стек: сначала скопировать всё, что является переменным, потом те параметры, которые мне нужно вставить, потом указатель на изменённую форматную строку. Но, наверное, это не дело, потому что программа будет привязана к конкретной системе (например, будет фиксированный размер указателя). Да и на ассемблере я длинее 20 команд ничего не писал, поэтому всё только в теории.
_________________
puts("hit");
printf("uck");
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
критикан



Зарегистрирован: 18.02.2005
Сообщения: 247

СообщениеДобавлено: Пт Мар 25 2005 16:50    Заголовок сообщения: Машины не думают -- машины работают. Ответить с цитатой

Алексей Инкин писал(а):
Вручную перебирать все аргументы тоже не хочется.

В стандарте С++ доходчиво написано, что ответственность за обработку аргументов функции с переменным количеством аргументов лежит на программисте. Точка. Поэтому аргументы придётся перебирать вручную. Со всеми последствиями.
--------------------------
Машины не думают -- машины работают.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Алексей Инкин



Зарегистрирован: 19.09.2004
Сообщения: 32
Откуда: Россия, Нижний Новгород

СообщениеДобавлено: Пт Мар 25 2005 18:37    Заголовок сообщения: Ответить с цитатой

В стандарте не это имают в виду. Можно создать функцию, и в ней реализовать все необходимые действия. Вот тогда нужно перебирать. А можно переадресовать весь набор переменных аргументов другой функции тоже с переменным их количеством. Специально для этого для каждой функции библиотеки есть эквивалент (printf->vprintf), такая переадресация делается очень просто:

va_list lstArguments;
va_start(lstArguments, strPrintfPattern);
vprintf(strPrintfPattern, lstArguments);
va_end(lstArguments);

А меня интересует почти то же самое, но плюс пропихнуть несколько дополнительных аргументов. Вот и всё.

Кстати, где можно почитать официальные тексты стандартов? Что-то мне интересно стало.
_________________
puts("hit");
printf("uck");
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
критикан



Зарегистрирован: 18.02.2005
Сообщения: 247

СообщениеДобавлено: Пн Мар 28 2005 08:56    Заголовок сообщения: Мыслить нужно просто. Как машины. Ответить с цитатой

Да понял я, что Вы хотите сделать. Я это не поддерживаю, но если очень уж хочется, то нужно взять описание va_list (из stdio.h или stdarg.h) и проинициализировать свой список самостоятельно. Например, так:

#include <stdio.h>
// в нём есть такое описание: typedef struct {
// char *a0; /* pointer to first homed integer argument */
// int offset; /* byte offset of next parameter */
//} va_list;

va_list lstArguments;
int lstArguments_size;
char *contentArguments_new;
#define newArg_size sizeof(char*);

...; // подсчёт количества рагументов и размера памяти, занятой аргументами, в зависимости от способа определения количества и типов переданных аргументов -- в случае vprintf() подсчёт выполняется по символам "%" в форматной строке

contentArguments_new=malloc(lstArguments_size+newArg_size);
...; //заносим в contentArguments_new свой аргумент и копируем переданные аргументы

va_start(lstArguments, *contentArguments_new);
и т. д.
----------------------
Мыслить нужно просто. Как машины.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Показать сообщения:   
Этот форум закрыт, вы не можете писать новые сообщения и редактировать старые.   Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.    Список форумов Архив форумов ЦИТФорума -> Программирование Часовой пояс: GMT + 3
Страница 1 из 1

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах


Powered by phpBB © 2001, 2002 phpBB Group
Русская поддержка phpBB

 

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 6608306, ICQ 232284597
Пресс-релизы — pr@citforum.ru
Послать комментарий
Информация для авторов
This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2006 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...