LINUX.ORG.RU

[C] snprintf и переменное число параметров

 


0

0

Дано:

1) массив double[], длина N которого известна на этапе компиляции.
2) строка F формата для snprintf, которая НЕ известна на этапе компиляции, а генерируется при выполнении и содержит N параметров (типа %f)

Надо:

в процессе выполнения программы выполнить типа snprintf(s, F, ...). Обычно вместо многоточия пишутся все параметры, т. е. они и их число известно на этапе компиляции, но в моём случае это не так. Что делать?

☆☆

вызови принтф несколько раз

anonymous
()

man vsnprintf
man __VA_ARGS__

// fatamer

anonymous
()

>длина N которого известна на этапе компиляции.

>содержит N параметров (типа %f)

>их число известно на этапе компиляции, но в моём случае это не так

я один вижу противоречие? количество параметров на этапе компиляции тебе известно, оно равно N

jtootf ★★★★★
()

Можно побаловаться особой, препроцессорной магией, т.е. написать макрос, разворачивающий PARAMS(x, n) в x[0], x[1], x[2], ..., x[n-1] и писать snprintf(s, format, PARAMS(x, sizeof(x) / sizeof(x[0])))

Как написать - вопрос интересный, я сходу не напишу, но советую посмотреть http://www.boost.org/doc/libs/1_36_0/libs/preprocessor/doc/index.html

Legioner ★★★★★
()
Ответ на: комментарий от dilmah

Тогда проще разбирать строку формата на кусочки по %f, и для каждого кусочка в цикле вызывать принтф. Дешево и сердито.

wfrr ★★☆
()
Ответ на: комментарий от dilmah

А параметры из массива в ручную набирал? или генерилбы подключаемый модуль кодом, компилил загружал и потом вызывал?

wfrr ★★☆
()
Ответ на: комментарий от wfrr

да, что-то я глюканул. Другие языки нужно юзать, в которых можно в рантайме аргументы собрать:)

dilmah ★★★★★
()
Ответ на: комментарий от ip1981

Короче, уточняю проблему: развернуть массив в список, и хотя размер массива известен до компиляции, его можно легко поменять, но саму программу менять не охота, то есть алгоритм разворячивания должен быть постоянным.

ip1981 ☆☆
() автор топика

Т.е. вам нужен Common Lisp, но ещё просто не осознали вы эту необходимость.

marsijanin ★★
()
Ответ на: комментарий от ip1981

#include <stdio.h>
#include <boost/preprocessor/repeat.hpp>

#define PRINTF_FORMAT(z,n,d) " %f"
#define PRINTF_ARR(z,n,d) ,d[n]

#define PRINTF(format_prefix, format_suffix, arr, n) \
    printf(format_prefix BOOST_PP_REPEAT(10, PRINTF_FORMAT, ~) format_suffix BOOST_PP_REPEAT(10, PRINTF_ARR, arr))

int main(int artc, char *argv[])
{
    float array[10] = {0,1,2,3,4,5,6,7,8,9};
    PRINTF("my array:", "\n", array, sizeof(array)/sizeof(array[0]));
    return 0;
}

и никаких шаблонов

anonymous
()
Ответ на: комментарий от anonymous

#include <stdio.h>
#include <boost/preprocessor/repeat.hpp>

#define PRINTF_FORMAT(z,n,d) " %f"
#define PRINTF_ARR(z,n,d) ,d[n]

#define PRINTF(format_prefix, format_suffix, arr, n) \
    printf(format_prefix BOOST_PP_REPEAT(n, PRINTF_FORMAT, ~) format_suffix BOOST_PP_REPEAT(n, PRINTF_ARR, arr))

int main(int artc, char *argv[])
{
    float array[10] = {0,1,2,3,4,5,6,7,8,9};
    PRINTF("my array:", "\n", array, 10);
    return 0;
}


fixed.

anonymous
()
Ответ на: комментарий от anonymous

Думаю в подобных случаях надо скопировать макрос BOOST_PP_REPEAT в программу и избавить от зависимости от Буста =)

ip1981 ☆☆
() автор топика
Ответ на: комментарий от anonymous

> и никаких шаблонов

не умеет препроцессор делать циклы и/или рекурсию. Посмотри определение этого PP_REPEAT и ты обнаружишь там шаблоны.

dilmah ★★★★★
()
Ответ на: комментарий от anonymous

все определение PP_REPEAT займет экранов 5. Вообще, использовать так препроцессор - большой изврат, т.к. там еще есть завязка на тип препроцессора: для MSVC делаем так, для GCC - по другому.

anonymous
()

офигеть, на какие только извращения с ц++ идут лишь бы не сделать нормально

уже было сказано man vsprint


-- Function: int vsnprintf (char *S, size_t SIZE, const char
*TEMPLATE, va_list AP)
This is the equivalent of `snprintf' with the variable argument
list specified directly as for `vprintf'.

denisko
()
Ответ на: комментарий от denisko

> уже было сказано man vsprint

ну так нельзя самому собрать va_list (скажем, массив превратить в va_list).

Ты можешь только передать va_list который тебе самому передали уже в виде аргументов.

dilmah ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.