使用GlibC,Windows中_snscanf()的模拟是什么?

时间:2012-02-23 05:18:15

标签: c linux curl libcurl glibc

我已经开始查看cURL的示例,在C中。编译ftpuploadresume.c时,我收到了未定义的引用错误:

/* _snscanf() is Win32 specific */
r = _snscanf(ptr, size * nmemb, "Content-Length: %ld\n", &len);

我只想知道glibc的_snscanf的替代方法是什么。

2 个答案:

答案 0 :(得分:3)

假设您使用空终止字符串,您可以完全安全地使用sscanf()而不使用第二个(长度)参数。你也可以在Windows上。如果您不知道该字符串是否为null,但您知道它有多长,请添加null终止符。 (如果您不知道该字符串有多长并且不知道它是否为空终止,没有是安全的!)

假设您有一个C99编译器,您可以自动进行必要的更改:

#define _snscanf(data, length, format, ...) scanf(data, format, __VA_ARGS__)

小心!

请注意comment namey - 为此,谢谢。

查看_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