MySQL Динамический размер строки помощника запросов с vsprintf (C ++) - PullRequest
1 голос
/ 22 октября 2019

У меня есть такая функция, ранее реализованная в C и теперь перемещенная в C ++.

   int StmtExec(MYSQL *db, const char *query, va_list params) {
        char q[512];
        vsprintf(q, query, params);
        printf("Query %s\n", q);
        int result = mysql_query(db, q);
        if (result) {
            logger_error("%s\n", mysql_error(db));
        }
        return result;
    }

Функция создает char q[512], размер которого ограничен 512. Но я бы хотел неограниченный (динамический) размер запросас std::string Мне все еще нужно применить запрос в качестве шаблона, поэтому мне нужно это vsprintf

Честно говоря, я не совсем хорош в C ++ ... Возможно ли это?

Я нашелэта функция: https://en.cppreference.com/w/cpp/io/c/vfprintf и пробовал с C ++, но он не работает со строкой C ++. Пытался использовать q.c_str, но это тоже не компилируется ...

1 Ответ

1 голос
/ 22 октября 2019

Это возможно. Вы можете сделать это так же, как в 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...