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

问题描述 投票:1回答:1

我以前用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,但是它也不能编译...

c++ mysql string stl
1个回答
0
投票

有可能。除了可以使用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;
© www.soinside.com 2019 - 2024. All rights reserved.