Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.07.2012, 18:05   #1
stranger84
Пользователь
 
Регистрация: 09.07.2012
Сообщений: 11
По умолчанию Передача в функцию переменного кол-ва аргументов РАЗНЫХ типов

Good Day Everyone!
Пишу прогу под контроллер и в связи с особенностями архитектуры столкнулся с такой проблемой.
Есть несколько переменных char [] (ASCII строки) при чём каждая может содержать просто текст типа "ля-ля-ля", а может и иметь токен prinft-типа "%d" или "%f". После массивов char-ов идут переменные типа int или float значения которых нужно подставить вместо "%d" или "%f".

То есть для примера:

Код:
char str1[] = "_a = ";
char str2[] = "_%d_";  // символ _ - это типа пробел :)
char str3[] = "ещё текст";
char str4[] = "_%f_";
char result_str[255];  //сюда надо впихнуть отпарсенный текст
int var1 = 5;
float var2 = 10.0;

// первым параметром идёт буфер (result_str), 
//следующими - те все перечисленные параметры
void parser(char *buf, ...) 
{
...
}



то есть как видите, нужно сделать свой аналог функции printf
проблема в том что при использовании va_list-va_start жёстко задаётся только один тип данных, а у меня их три (1 - строка, 2 - int, 3 - float)

гугл спрашивал. он не знает.
напомню что пишу под контроллер, поэтому БЕЗ классов и С++ вещей, то есть чистый ANSI C.

кто подскажет хотя бы как передать и разобраться внутри функции где какая переменная какого типа буду ДИКО благодарен

заранее спасибо

Последний раз редактировалось stranger84; 10.07.2012 в 10:41.
stranger84 вне форума Ответить с цитированием
Старый 09.07.2012, 20:36   #2
Петррр
Форумчанин
 
Аватар для Петррр
 
Регистрация: 02.09.2011
Сообщений: 336
По умолчанию

http://www.cplusplus.com/reference/c...stdio/sprintf/ не канает уже?
Если ты не можешь найти то, ради чего стоит жить, лучше найти то, за что стоит умереть
Петррр вне форума Ответить с цитированием
Старый 09.07.2012, 20:45   #3
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

ну начнем с того что вы указываете именно в va_arg тип аргумента.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 09.07.2012, 22:00   #4
stranger84
Пользователь
 
Регистрация: 09.07.2012
Сообщений: 11
По умолчанию

Цитата:
Сообщение от Петррр Посмотреть сообщение
Цитата:
напомню что пишу под контроллер
как бэ..ограничение по объёму кода...да и быстродействие тоже имеет значение..(2 раза вызывать функцию если можно реализовать всё внутри)

Цитата:
Сообщение от Пепел Феникса
ну начнем с того что вы указываете именно в va_arg тип аргумента.
синтаксис допускает двукратное определение разных типов в одной va_list структуре ?
или вы предлагаете создать 2 определения va_list с разными объявлениями типов ?
stranger84 вне форума Ответить с цитированием
Старый 10.07.2012, 08:34   #5
Krok27
Форумчанин
 
Аватар для Krok27
 
Регистрация: 08.07.2010
Сообщений: 505
По умолчанию

Код:
int sum ( int count , . . . )
{
va_list vl ;
int result = 0 ;
va_start (vl , count ) ;
for ( ; count > 0 ; count - - )
{
result += va_arg (vl , int ) ;
}
va_end (vl ) ;
return result ;
}
Использование:

Код:
int x , y ;
x = sum ( 5 , 1 , 2 , 3 , 4 , 5 ) ; /* сумма пяти чисел */
y = sum ( 3 , 1 , 2 , 3 ) ; /* сумма трех чисел */
Знающий не говорит, говорящий не знает (С) Лао Цзы
Krok27 вне форума Ответить с цитированием
Старый 10.07.2012, 09:44   #6
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
синтаксис допускает двукратное определение разных типов в одной va_list структуре ?
или вы предлагаете создать 2 определения va_list с разными объявлениями типов ?
va_list структура вас не ограничивает в типах, читаете вы через va_arg.
printf(и иже с ними) же работает.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 10.07.2012, 10:50   #7
stranger84
Пользователь
 
Регистрация: 09.07.2012
Сообщений: 11
По умолчанию

Krok27, спасибо за текст, но задача в том чтобы нужно сделать свой аналог функции printf
то бишь, функция будет вызыватся так:

Код:
// объявление
void parser(char *buf, ...) 
{
...
}

void main()
{
     char str[5];
     // предпоследняя переменн - int, последняя - float 
     parser(str, " a = ", " %d ", "__", "%f", 5, 10.0)
}
Пепел Феникса, спасибо, буду пробывать если ещё появятся идеи - с радостью выслушаю
stranger84 вне форума Ответить с цитированием
Старый 10.07.2012, 12:46   #8
Kostia
Участник клуба
 
Аватар для Kostia
 
Регистрация: 21.11.2007
Сообщений: 1,690
По умолчанию

поизвращался :D
Код:
#include <stdarg.h>
#include <stdio.h>

void print(const char *format, ...){
    va_list p;
    va_start(p, format);
    int i = 0, j;
    char s[20];
    char *ds;
    int dec, sign;
    while(format[i]){
        if(format[i]=='%'){
            i++;
            switch(format[i]){
                case 'd':
                    ZeroMemory(s,20);
                    itoa((int)va_arg(p, int), s, 10);
                    for(j = 0; s[j]; j++){
                        putchar(s[j]);
                    }
                break;
                case 'f':
                    ds = ecvt(va_arg(p, double), 6, &dec, &sign);
                    if(sign) putchar('-');
                    if(dec == 0) putchar('0');
                    for(j = 0; ds[j]; j++){
                        if(j==dec) putchar('.');
                        putchar(ds[j]);
                    }
                break;
            }
            i++;
        }
        putchar(format[i]);
        i++;
    }
    va_end(p);
}

int main()
{
    print("int: %d %d %d\nfloat: %f %f %f\n", 5, 7, 25, 5.5, 7.7, -2.0/3.0);
    return 0;
}
Kostia вне форума Ответить с цитированием
Старый 10.07.2012, 12:49   #9
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

stranger84, не забывайте что ваша функция должна как то узнать сколько у нее аргументов и их типы.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 10.07.2012, 13:05   #10
Krok27
Форумчанин
 
Аватар для Krok27
 
Регистрация: 08.07.2010
Сообщений: 505
По умолчанию

Или обрабатывать пока не 0.
Знающий не говорит, говорящий не знает (С) Лао Цзы
Krok27 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Передача аргументов в функции по ссылке skanku Общие вопросы C/C++ 2 11.01.2012 21:24
Передача в функцию неограниченного количества аргументов pronaks Общие вопросы C/C++ 4 13.12.2011 22:54
передача разных типов данных из Exel в Access zinch Microsoft Office Excel 1 10.11.2011 19:54
Передача аргументов в функцию. C++ Kholmansky Помощь студентам 2 15.09.2011 01:02
Как передать в функцию параметр разных типов borispnz Общие вопросы Delphi 5 06.02.2010 08:37