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

发布于 2025-01-07 21:48:08 字数 241 浏览 3 评论 0原文

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

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

我只想知道 _snscanf 的替代方案是什么代码> glibc。

I have started going through the samples of the cURL, in C. While compiling ftpuploadresume.c I am getting undefined reference error at:

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

I just want to know what is the alternative to _snscanf for glibc.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吹梦到西洲 2025-01-14 21:48:08

假设您使用以 null 结尾的字符串,则可以完全安全地使用 sscanf() ,而无需第二个(长度)参数。在 Windows 上也可以。如果您不知道字符串是否以 null 终止,但您知道它有多长,请添加 null 终止符。 (如果您不知道字符串有多长,也不知道它是否以 null 结尾,那么没有是安全的!)

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

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

提防!

请注意评论< /a> 由 namey — 谢谢。

查看 _snscanf()< 上的 Microsoft 手册页/a>.这些例子并不具有说服力;即使没有指定长度,你也会得到相同的结果。然而,看起来@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;
}

Assuming you use null terminated strings, you can perfectly safely use sscanf() without the second (length) argument. You could on Windows, too. If you don't know that the string is null terminated but you do know how long it is, add the null terminator. (If you don't know how long the string is and don't know whether it is null terminated, nothing is safe!)

Assuming you have a C99 compiler, you can work the necessary change automatically:

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

Beware!

Note the comment by namey — for which, thanks.

Look at the Microsoft man pages on _snscanf(). The examples are not compelling; you'd get the same results even without the length being specified. However, it does look as though @namey is correct in general. A lot is going to depend on the context in which it is used. If the length specified is actually strlen(data), then the difference isn't going to matter. If the length specified is longer than that, the difference probably isn't going to matter. If the length is smaller than the length of the data, the difference might matter quite a lot.

A better cover function might be:

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;
}
人生百味 2025-01-14 21:48:08

如果您确定传递给_snscanf的字符串是有效的空终止字符串,您可以简单地使用sscanf(3)%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 可能已被设置。

顺便说一句,我的解决方案不是 GNU glibc 特定的,它应该与其他 POSIX 兼容的 libc-s 一起使用就像 musl-libc

If you are sure that the string passed to _snscanf is a valid null-terminated string, you could simply use sscanf(3) with %n e.g.

 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;
 }

The %n conversion specification sets the pointed integer to the current scanning offset. So we use sscanf, it may scan past the limit, but in that case we reject the scan (by setting r = 0). Of course, we have to accept that len could have been set.

BTW, my solution is not GNU glibc specific, it should work with other POSIX compliant libc-s like musl-libc

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文