Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 23, средняя оценка - 4.83
alex63
0 / 0 / 0
Регистрация: 29.04.2015
Сообщений: 3
#1

Как создать va_list для _vsntprintf ? - C++

11.02.2009, 15:52. Просмотров 2846. Ответов 2
Метки нет (Все метки)

Программирование хобби. В основном программирую на Autolispe.

Хотелось бы иметь функцию аналогичную swprintf или _vsntprintf
Написал функцию для одного аргумента через вызов swprintf(szBuffer,format,var);
Хотелось бы иметь На autoLispe ->(format "%s %d %f" "Test=" 120 63.4)
функцию с переменным количеством аргументов.

На Си ->_vsntprintf(szBuffer, sizeof(szBuffer)/izeof(szBuffer[0]), lpszFormat, args)
где va_list это args .

Как создать тип va_list ?
Какова структура списка va_list ?
Во всех примерах показано как обработать функцию с переменным кол-вом аргументов.
Но как создать самому тип va_list?
Подскажите кто знает?
Заранее благодарен.


Пример функции format для AutoLisp с 1им аргументом (format "T=%d" 10)-> "T=10"

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
static int ads_format(void)
    {
        struct resbuf  *rb=acedGetArgs () ;
        struct resbuf *p;
 
        p=rb;
 TCHAR format[512];
 TCHAR buff[512];
 TCHAR *ret;
 TCHAR vs[512];
int i1;
double d1;
 
if(rb == NULL) return RTNORM;
 
if (rb->restype == RTSTR) wcscpy(format,rb->resval.rstring);//strcpy
  else {  acdbFail(_T("\n1 Argument should be an string."));
       return (RTERROR); 
  }
 rb=rb->rbnext;
if(rb == NULL) { //acutPrintf(temp);
                 ret=strsave(buff);
                 acedRetStr(ret);                
                 return (RSRSLT) ;
}
if (rb->restype == RTSTR)  {
  wcscpy(vs,rb->resval.rstring); // строка
  swprintf(buff,format,vs);     
}
else if (rb->restype == RTSHORT)  // целое
 {
   i1=rb->resval.rint;   
   swprintf(buff,format,i1);
 }
  else if(rb->restype == RTREAL) // вещественное
  {
    d1=rb->resval.rreal;    
    swprintf(buff,format,d1);   
  }
   else
   {
      acdbFail(_T("\n2 Argument should be an integer double string."));   
      return (RSRSLT) ;
   }
 
ret=strsave(buff);
 
acedRetStr(ret);
ads_relrb(p);
return (RSRSLT);
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.02.2009, 15:52
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как создать va_list для _vsntprintf ? (C++):

Как работать с va_list? - C++
Есть функция: std::wstring APP::Execute (std::wstring scrName, wchar_t *args,...) { va_list ArgsL; va_start(ArgsL,args); ...

Не работает snprintf с va_list C++98 - C++
Хочу собрать функцию вывода на подобии printf, но немогу понять почему snprintf делает пустоту, хотя результат его > 0 const...

vwprintf, va_list (stdarg.h) и большие числа (больше 4х байт) - C++
Здравствуйте Вызывается метод: CLog::okf(L"\n\tSector size:\t%u\n\tSectors count:\t%u\n\tDisk size:\t%u", dwSectorSize,...

Как можно бы создать метод для ввода размерности (т.е. для ввода private переменных n,m)? - C++
Как можно бы создать метод для ввода размерности (т.е. для ввода private переменных n,m)? ( что только я не пробывал: то переменные...

Создать стек для символов. Максимальный размер стека вводится с экрана. Создать функции для ввода и вывода элементов стека. Ввести эталонный символ. - C++
Создать стек для символов. Максимальный размер стека вводится с экрана. Создать функции для ввода и вывода элементов стека. Ввести...

Как создать фигуры для тетриса? - C++
Привет всем! Захотел написать простенькую игру и решил начать с тетриса. Пишу в visual studio 2013 c++. Как и всегда появляются проблемы: ...

2
XuTPbIu_MuHTAu
Эксперт С++
2227 / 742 / 10
Регистрация: 27.05.2008
Сообщений: 1,498
11.02.2009, 16:54 #2
Цитата Сообщение от alex63 Посмотреть сообщение
Как создать тип va_list ?
Какова структура списка va_list ?
Во всех примерах показано как обработать функцию с переменным кол-вом аргументов.
Но как создать самому тип va_list?
Подскажите кто знает?
Заранее благодарен.
Это не типы и не структуры,а всего лишь макросы. Их можно загуглить, чтобы увидеть,как именно они реализованы. Про автолисп я ничего не знаю,поэтому не уверен,что там такое возможно. На си это реализуется очень просто. Например, для cdecl функций параметры передаются справа налево. Допустим,в принтф передают три параметра. Стек будет выглядеть так:
...
АВ
АРГ1
АРГ2
АРГ3

Принтф определяет по первому параметру,сколько их еще в стеке. Адрес второго параметра вычисляется как адрес первого + sizeof(arg1). Этот самый sizeof определяется типом параметра,который, в свою очередь, определяется исходя из управляющих символов. Адрес третьего аргумента вычисляется точно также. Фактически, va_list всего лишь скрывает работу с адресами: все,что нужно знать - это что происходит со стеком при вызове функций.
0
alex63
0 / 0 / 0
Регистрация: 29.04.2015
Сообщений: 3
22.02.2009, 19:50 #3
Все работает. Получилась такая функция
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
static int ads_ak_format(void)
{
        struct resbuf  *rb=acedGetArgs () ;             
        // TODO: add your code here
 TCHAR format[512];
 TCHAR buff[1024]; 
 int sizeofVa_list=0;
  
if(rb == NULL) return RTNORM;
 
if (rb->restype == RTSTR) wcscpy(format,rb->resval.rstring);
  else {  acdbFail(_T("\n first  Argument should be an string. Example \"A= %s s=%d\""));
       return (RTERROR); 
  }
 rb=rb->rbnext; 
struct resbuf *p=rb;
sizeofVa_list=sizeofListVal(p);
const char *m=(char *)malloc(sizeof(sizeofVa_list));// +   sizeof(char));
void *bm=(void *)m;
while (rb != NULL) 
{
switch(rb->restype)
   {
case RTREAL: 
    (*(ads_real*)m)=rb->resval.rreal; //puts the next value
    m += sizeof(ads_real);  //(double); // move forward again
    break;
case RTSHORT :
    (*(int*)m)=(int)rb->resval.rint; //puts the next value      
    m += sizeof(int);// move forward again      
    break;
case RTLONG :
    (*(int*)m)=(int)rb->resval.rlong; //puts the next value
    m += sizeof(int);
    break;
case RTSTR :
    (* (TCHAR **)m)=rb->resval.rstring;
    m += sizeof(TCHAR *);
    break;
default :
    acutPrintf(_T("\n only type {double int string} ."));   
    break;
     }   
    rb=rb->rbnext;
   }// while
int ii=(_tcslen(buff)+1)*sizeof(TCHAR);
vswprintf(buff,ii,format,(va_list)bm);
acedRetStr(strsave(buff));
acutRelRb(rb);
free(bm);
return (RSRSLT) ;
    }
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.02.2009, 19:50
Привет! Вот еще темы с ответами:

Как создать файл для записи? - C++
Как правильно создать файл для записи,чтобы внести необходимое кол-во имен? #include<iostream> #include<assert.h> ...

Как создать интерфейс для программы? - C++
Здравствуйте. Подскажите, Как создать графический интерфейс. К примеру написал прогу(исходник), тот же конвертер валют или калькулятор...

как создать цикл для программы ? - C++
необходимо 4тобы программа не закрывалась после отладки, а продолжаласт .. например прописать: 1 - продолжить, 0 - выход ... подскажите ...

Как создать псевдоним для лямбды? - C++
ПРИВЕТ. не поможете ли советом, как решить проблему: хочу дать имя классу лямбды, но чето не выходит using PREDICATE = (const...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.