gpt4 book ai didi

C++ 中的 Python 风格字符串替换

转载 作者:行者123 更新时间:2023-11-28 00:14:05 24 4
gpt4 key购买 nike

显示在this中回答它的问题 Python 中的字符串替换是如何工作的。

我相信它是这样工作的

string toSql(string table, string field, string value)
{
string out;
return out = "INSERT INTO %s (%s) VALUES (%s)" % (table,field,value);
}

在没有文件 i/o 的情况下,在 C++ 中是否有类似的方法来执行此操作?

我正在尝试使用它来形成对 SQLite 数据库的查询。

编辑

我正在避免使用外部库。前提升

此外,输入是由程序提供的,而不是用户提供的。所以我不相信我会遇到注入(inject)漏洞

最佳答案

为了回答提出的问题,惯用的 C++ 方法是使用 std::ostringstream。请注意,此流类由内存支持,而不是磁盘上的文件。

(还有 snprintf() 选项,它看起来更接近 Python 字符串格式,但具有 C 风格的接口(interface),如果没有充分的理由,不应在现代 C++ 中使用。如果你正在编写 C++ 然后编写 C++,而不是 C。)

std::string toSql(
std::string const & table,
std::string const & field,
std::string const & value
) {
std::ostringstream s;

s << "INSERT INTO " << table
<< " (" << field << ") VALUES (" << value << ")";

return s.str();
}

但是,请注意,如果任何参数是未经过滤的用户输入,这会使您的程序遭受 SQL 注入(inject)攻击。您应该改为使用准备好的语句(sqlite3_prepare() 后跟 sqlite3_bind_...())将 value 绑定(bind)到语句中——但是您仍然需要从 tablefield 参数构建字符串,因为不能以这种方式绑定(bind)数据库对象名称。


您可以像这样“以 C++ 方式”使用准备好的语句(std::unique_ptr 需要 C++11 或更好的版本):

#include <memory>
#include <string>
#include <sqlite3.h>

// Deleter functor to properly sqlite3_finalize() statements when we
// are done with them.
struct sqlite3_stmt_deleter
{
void operator()(sqlite3_stmt * p) const {
sqlite3_finalize(p);
}
};

// Type alias for a std::unique_ptr that uses the above functor to
// clean up statements.
using sqlite3_prepared_stmt = std::unique_ptr<sqlite3_stmt, sqlite3_stmt_deleter>;

sqlite3_prepared_stmt prepare(sqlite3 * db, std::string const & sql)
{
sqlite3_stmt * stmt = nullptr;

// Note that we don't allow the caller to see any error information. A
// proper wrapper will want to throw if the return isn't SQLITE3_OK.
sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr);

return sqlite3_prepared_stmt(stmt);
}

void example() {
auto insert_stmt = prepare(
your_db,
"INSERT INTO foo (bar) VALUES (?)");

std::string value{"baz"};

// Bind value to the ? in the prepared statement
sqlite3_bind_text(insert_stmt.get(), 1, value.c_str(), -1, SQLITE_TRANSIENT);

// Execute statement.
sqlite3_step(insert_stmt.get());

// Reset statement so it can be used again with bind/step.
sqlite3_reset(insert_stmt.get());

// std::unique_ptr destructor will call sqlite3_finalize() for us.
}

使用此代码,您可以将 sqlite3_prepared_stmt 存储在某处并重新使用它。

关于C++ 中的 Python 风格字符串替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31431613/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com