C99标准草案没有明确说明在这些情况下应该发生的情况,但是通过考虑多种变体,您可以证明它必须以某种方式工作,以便在所有情况下都符合规范。
该标准说:
%s-匹配一系列非空格字符(252)
如果不存在l长度修饰符,则相应的参数应为 指向字符数组的初始元素的指针,该元素的大小足以接受 序列和终止的空字符,这些字符将自动添加。
这是一对示例,说明它必须按照您提出的符合标准的方式工作。
Example A:
char buffer[4] = "abcd";
char buffer2[10]; // Note the this could be placed at what would be buffer+4
sscanf("123 4", "%s %s", buffer, buffer2);
// Result is buffer = "123\0"
// buffer2 = "4\0"
范例B:
char buffer[17] = "abcdefghijklmnop";
char* buffer2 = &buffer[4];
sscanf("123 4", "%s %s", buffer, buffer2);
// Result is buffer = "123\04\0"
请注意,sscanf的界面没有提供足够的信息来真正知道它们是不同的。 因此,如果示例B要正常工作,则它必须不弄乱示例A中空字符之后的字节。这是因为根据这部分规范,它必须在两种情况下都可以工作。
因此,隐含地它必须按照规范说明工作。
可以为其他函数放置类似的参数,但是我认为您可以从此示例中看到这个想法。
注意:以“%16s”之类的格式提供大小限制可能会改变行为。 根据规范,在将数据写入缓冲区之前,sscanf将缓冲区归零到其极限在功能上是可以接受的。 实际上,大多数实现都选择性能,这意味着它们将其余的问题搁置一旁。
当规范的目的是进行这种归零时,通常会明确指定它。 strncpy是一个示例。 如果字符串的长度小于指定的最大缓冲区长度,则它将用空字符填充其余空间。 同样的“字符串”函数也可以返回未终止的字符串的事实,使之成为人们推出自己版本的最常见函数之一。
至于fget,可能会出现类似的情况。 唯一的麻烦是,该规范明确指出,如果未读取任何内容,则缓冲区保持不变。 可接受的功能实现可以通过在将缓冲区清零之前检查是否有至少一个字节要读取来避开此情况。