我以前用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
,但这还不能编译...
答案 0 :(得分:1)
有可能。您可以使用与C语言相同的方法来执行此操作,除了您可以使用std::string
(或者可以使用std::vector<char>
,因为它仅用作缓冲区)而不是{{1} }。
首先使用nullptr调用malloc
,以便它不写任何内容。然后使用返回的大小分配缓冲区。最后调用vsnprintf
。但是要使用两次参数列表,必须使用vsprintf
复制它。示例:
va_copy
也就是说,标准的C I / O API使用起来很棘手,并且容易出错,尤其是(但不仅限于)无经验的人。
C ++ iostream是一种更安全的替代方法(但它们也不完美)。 C ++ 20将引入一个新的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);
函数,该函数应同时兼顾两个方面。
第一个vsnprintf看起来有些开销
这就是为您提供的C I / O API;要么接受,要么离开它。就是说,与db查询本身相比,我希望开销很小。
是否可以在iostream中重用相同的字符串模板
您不能在iostream中使用格式字符串。相反,可以执行以下操作:
std::format