Это возможно. Вы можете сделать это так же, как в C, за исключением того, что вы используете std::string
(или вы можете использовать std::vector<char>
, поскольку он используется просто как буфер) вместо malloc
.
Первый вызов vsnprintf
с nullptr, чтобы он ничего не записывал. Затем используйте возвращенный размер для выделения буфера. Наконец позвоните vsprintf
. Но чтобы использовать список аргументов дважды, вы должны продублировать его с помощью va_copy
. Пример:
va_list params_copy;
va_copy(params_copy, params);
int len = vsnprintf(nullptr, 0, query, params_copy);
va_end(params_copy);
std::string q(len + 1, '\0');
vsprintf(q.data(), query, params);
Тем не менее, стандартный API CI / O сложно использовать и подвержен ошибкам, особенно (но не исключительно) со стороны неопытных.
Iostreams C ++ безопаснееальтернатива (но они тоже не идеальны). C ++ 20 представит новую функцию std::format
, которая должна предложить лучшее из обоих миров.
этот первый vsnprintf выглядит как дополнительная нагрузка
Это API CI / O для вас;возьми это или оставь. Тем не менее, я ожидаю, что издержки будут крошечными по сравнению с самим запросом базы данных.
Можно ли повторно использовать тот же шаблон строки с iostream
Вы не можетеиспользовать строки формата с iostreams. Вместо этого можно сделать что-то вроде:
query << "SELECT " << columns << " FROM " << table << " WHERE " << conditions;