首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Formatted String Printing Functions

代码语言:javascript
复制
char *sqlite3_mprintf(const char*,...);
char *sqlite3_vmprintf(const char*, va_list);
char *sqlite3_snprintf(int,char*,const char*, ...);
char *sqlite3_vsnprintf(int,char*,const char*, va_list);

这些例程与标准C库中的“printf()”函数系列具有同样的功能。这些例程可以理解大多数常见的K&R格式选项,以及一些额外的非标准格式,详情如下。请注意,这个实现中省略了最近C库标准中一些比较晦涩的格式化选项。

sqlite3_mprintf()和sqlite3_vmprintf()例程将其结果写入从sqlite3_malloc()获取的内存中。这两个例程返回的字符串应该由sqlite3_free()释放。如果sqlite3_malloc()无法分配足够的内存来存放结果字符串,那么这两个例程都会返回一个NULL指针。

sqlite3_snprintf()例程与标准C库中的“snprintf()”类似。结果被写入作为第二个参数提供的缓冲区,其大小由第一个参数给出。请注意,前两个参数的顺序与snprintf()相反。这是一个历史性的事故,如果不打破向后兼容性,这是不能修复的。还要注意,sqlite3_snprintf()返回一个指向其缓冲区的指针,而不是实际写入缓冲区的字符数。我们承认写入的字符数量是一个更有用的返回值,但是我们现在不能改变sqlite3_snprintf()的实现而不会破坏兼容性。

只要缓冲区大小大于零,sqlite3_snprintf()就可以确保缓冲区总是以零终止。第一个参数“n”是缓冲区的总大小,包括零终止符的空间。所以可以完全写入的最长的字符串将是n-1个字符。

sqlite3_vsnprintf()例程是sqlite3_snprintf()的可变参数版本。

这些例程都实现了一些额外的格式化选项,这些选项对构建SQL语句很有用。所有通常的printf()格式选项都适用。此外,还有"%q", "%Q", "%w" 和 "%z" 选项。

%q选项像%s一样工作,它从参数列表中替换了一个以nul结尾的字符串。但%q也会使每个'\'字符加倍。%q是为在字符串文字中使用而设计的。通过将每个'\''字符加倍,它将转义该字符并允许将其插入到字符串中。

例如,假定字符串变量zText包含以下文本:

代码语言:javascript
复制
char *zText = "It's a happy day!";

可以在SQL语句中使用此文本,如下所示:

代码语言:javascript
复制
char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
sqlite3_exec(db, zSQL, 0, 0, 0);
sqlite3_free(zSQL);

由于使用了%q格式的字符串,因此zText中的'\'字符将被转义,并且生成的SQL如下所示:

代码语言:javascript
复制
INSERT INTO table1 VALUES('It''s a happy day!')

这是对的。如果我们使用%s而不是%q,生成的SQL将如下所示:

代码语言:javascript
复制
INSERT INTO table1 VALUES('It's a happy day!');

第二个示例是SQL语法错误。作为一般规则,当将文本插入到字符串文字中时,应始终使用%q而不是%s。

%Q选项与%q一样工作,除了它还在总字符串的外部添加单引号。此外,如果参数列表中的参数是NULL指针,则%Q将替换文本“NULL”(不带单引号)。所以,例如,可以说:

代码语言:javascript
复制
char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
sqlite3_exec(db, zSQL, 0, 0, 0);
sqlite3_free(zSQL);

即使zText变量是NULL指针,上面的代码也会在zSQL变量中显示正确的SQL语句。

“%w”格式选项与“%q”类似,不同之处在于它预期包含在双引号而不是单引号内,并且它转义双引号字符而不是单引号字符。“%w”格式选项旨在将表名和列名安全地插入到构造的SQL语句中。

“%z”格式选项的工作方式与“%s”相似,但除了在字符串被读取并复制到结果中之后,sqlite3_free()在输入字符串上被调用。

扫码关注腾讯云开发者

领取腾讯云代金券