允许 NULL arg 进行 sscanf?
是否允许使用 NULL
指针作为调用 sscanf
时存储结果的字符串?
我在任何文档中都没有找到任何有关它的信息,但它似乎工作正常。 scanf
也是如此。
示例:
int main(int arc, char* argv[])
{
char* s = NULL;
sscanf("Privjet mir!", "%s", s);
printf("s: %s\n", s);
return 0;
}
输出:s: (null)
Is a NULL
pointer allowed as the string to store result in in a call to sscanf
?
I don't find anything about it in any documentation but it seems to be working fine. Same thing with scanf
.
Example:
int main(int arc, char* argv[])
{
char* s = NULL;
sscanf("Privjet mir!", "%s", s);
printf("s: %s\n", s);
return 0;
}
Output: s: (null)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
不:
(http://linux.die.net/man/3/sscanf)
No:
(http://linux.die.net/man/3/sscanf)
正如其他答案所提到的,
NULL
不能作为附加参数传递给sscanf
。http://www.cplusplus.com/reference/cstdio/sscanf 说附加论点:
对于
%s
说明符,这些提取的字符是:所以当存储“非空白字符”和“终止空字符”时,就会出现段错误。这正是 Visual Studio 将产生的结果(您可以在 http://webcompiler.cloudapp.net/< 处测试这是否失败/a>):
现在,对于非 Visual Studio 编译器,libc 的
%s
说明符的提取代码: com/ffainelli/uClibc/blob/master/libc/stdio/_scanf.c#L1376" rel="nofollow noreferrer">https://github.com/ffainelli/uClibc/blob/master/libc/stdio/_scanf.c #L1376 具有主要注释:/* 我们可能必须自己处理分配 */
这是因为:[来源]
因此,因为 libc 提取到内部构造为
sscanf< 的缓冲区/code> 并随后检查缓冲区参数在分配之前是否没有设置标志,它永远不会将字符写入
NULL
缓冲区参数。我必须强调这是非标准的,并且即使在次要的库更新之间也不能保证被保留。更好的方法是使用
*
子说明符:[来源]
这可以像这样完成,例如:
显然是真实的三元的 -branch 是一个无操作,但我将其包含在内,期望从字符串中读取其他数据。
As is mentioned by the other answers
NULL
is not valid to pass tosscanf
as an additional argument.http://www.cplusplus.com/reference/cstdio/sscanf says of additional arguments:
For the
%s
specifier these extracted characters are:So when the "non-whitespace characters" and "terminating null character" is stored, there will be a segfault. Which is exactly what Visual Studio will yield (you can test that this fails at http://webcompiler.cloudapp.net/):
Now as far as non-Visual Studio compilers, libc's extraction code for the
%s
specifier: https://github.com/ffainelli/uClibc/blob/master/libc/stdio/_scanf.c#L1376 has the leading comment:/* We might have to handle the allocation ourselves */
this is because:[Source]
So because libc extracts to a buffer constructed internally to
sscanf
and subsequently checks that the buffer parameter has no flags set before assigning it, it will never write characters to aNULL
buffer parameter.I can't stress enough that this is non-standard, and is not guaranteed to be preserved even between minor library updates. A far better way to do this is to use the
*
sub-specifier which:[Source]
This could be accomplished like this for example:
Obviously the true-branch of the ternary is a no-op, but I've included it with the expectation that other data was expected to be read from the string.
联机帮助页指出,当使用
%s
时,参数必须是一个具有足够空间容纳字符串和\0
的指针。所以我的猜测是你的情况的行为是未定义的。它可能会起作用,也可能会崩溃或损坏内存并在以后引起问题。The manpage says that, when using
%s
, the argument must be a pointer with enough space for the string and\0
. So my guess would be that the behaviour in your case is undefined. It may work, it may also crash or corrupt memory and cause issues later.不,这是不允许的。
sscanf %s 需要一个 char* 指向足够大的缓冲区,printf %s 需要一个 nul char* 缓冲区。其他任何事情都会导致未定义的行为。 (这意味着某些实现可能会以某种方式检测和处理空指针,其他实现可能不会)
No, this is not allowed.
sscanf %s expects a char* pointing to a sufficient large buffer, printf %s wants a nul char* buffer. Anything else results in undefined behavior. (And that means some implementations might detect and handle a null pointer in a certain way, other implementations might not)
我在标准中没有找到任何明确涉及
NULL
和*printf
/*scanf
的内容。我认为这是未定义的行为1,因为它被视为传递与格式说明符不一致的参数(§7.19.6.1 ¶13、§7.19.6.2 ¶13):
%s
意味着您将传递一个指向字符数组第一个元素的指针(对于*scanf
获取的字符串来说足够大,包含一个NUL< /code> 终止的字符串为
*printf
) - 并且传递NULL
不能满足此要求。1. In this case UB shows as "just ignoring the acquisition" and "printing (null)", on other platforms it may result in planes falling down the sky or the usual nasal demons.
I didn't find anything in the standard explicitly concerning
NULL
and*printf
/*scanf
.I suppose that this is undefined behavior1, since it counts as passing an argument that is not coherent with the format specifier (§7.19.6.1 ¶13, §7.19.6.2 ¶13):
%s
means that a you're going to pass a pointer to the first element of a character array (large enough for the acquired string for*scanf
, containing aNUL
-terminated string for*printf
) - and passingNULL
doesn't satisfy this requirement.1. In this case UB shows as "just ignoring the acquisition" and "printing (null)", on other platforms it may result in planes falling down the sky or the usual nasal demons.
将内存分配给 s 。将 s 分配给字符数组。然后运行程序。
以下将起作用。
Allocate the memory to s . Assign s to character array. Then run the program.
Following will work.