我已经开始查看cURL的示例,在C中。编译ftpuploadresume.c
时,我收到了未定义的引用错误:
/* _snscanf() is Win32 specific */
r = _snscanf(ptr, size * nmemb, "Content-Length: %ld\n", &len);
我只想知道glibc的_snscanf
的替代方法是什么。
答案 0 :(得分:3)
假设您使用空终止字符串,您可以完全安全地使用sscanf()
而不使用第二个(长度)参数。你也可以在Windows上。如果您不知道该字符串是否为null,但您知道它有多长,请添加null终止符。 (如果您不知道该字符串有多长并且不知道它是否为空终止,没有是安全的!)
假设您有一个C99编译器,您可以自动进行必要的更改:
#define _snscanf(data, length, format, ...) scanf(data, format, __VA_ARGS__)
查看_snscanf()
上的Microsoft手册页。这些例子并不引人注目;即使没有指定长度,你也会得到相同的结果。但是,它看起来好像@namey一般是正确的。很多将取决于使用它的上下文。如果指定的length
实际上是strlen(data)
,则差异无关紧要。如果指定的长度超过该长度,则差异可能不重要。如果长度小于数据的长度,则差异可能非常重要。
更好的封面功能可能是:
int _snscanf(const char *input, size_t length, const char *format, ...)
{
char *copy = malloc(length + 1);
if (copy == 0)
return 0;
memmove(copy, input, length);
copy[length] = '\0';
va_list args;
va_start(args, format);
int rc = vsscanf(copy, format, args);
va_end(args);
free(copy);
return rc;
}
答案 1 :(得分:0)
如果您确定传递给_snscanf
的字符串是一个有效的以空字符结尾的字符串,您只需将man page与%n
一起使用,例如
int pos = -1;
int limit = size * nmemb;
r = sscanf(ptr, "Content-Length: %ld\n%n", &len, &pos);
if (r>0 && pos >= limit) {
r = 0;
len = -1;
}
%n
转换规范将指向的整数设置为当前扫描偏移量。因此我们使用sscanf
,它可能扫描超过限制,但在这种情况下,我们拒绝扫描(通过设置r = 0
)。当然,我们必须接受len
可以设置。
BTW,我的解决方案不是sscanf(3)特定的,它应该适用于其他符合POSIX标准的libc-s,如GNU glibc