我以前用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
,但是它也不能编译...
有可能。除了可以使用std::string
(或者可以使用std::vector<char>
,因为它仅用作缓冲区)而不是malloc
,您可以像在C中一样进行操作。
首先使用nullptr调用vsnprintf
,这样它就不会写任何东西。然后使用返回的大小分配缓冲区。最后调用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);
也就是说,标准的C I / O API使用起来很棘手,特别是(但不是唯一地)由经验不足的人容易出错。
C ++ iostream是更安全的替代方法(但它们也不是完美的)。 C ++ 20将引入一个新的std::format
函数,该函数应同时兼顾两个方面。
第一个vsnprintf看起来有些开销
这就是您的C I / O API;要么接受,要么离开它。就是说,与db查询本身相比,我希望开销很小。
是否可以在iostream中重用相同的字符串模板
您不能在iostream中使用格式字符串。相反,可以执行以下操作:
query << "SELECT " << columns << " FROM " << table << " WHERE " << conditions;