MySQL带有vsprintf的查询助手的动态字符串大小(C ++)

时间:2019-10-22 02:44:58

标签: c++ mysql string stl

我以前用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 个答案:

答案 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