标准在这方面有些模糊,但我认为合理的解读是:是的,在缓冲区中写入的字节数不能超过读取的字节数加上空字符。另一方面,对文本的更严格解读/解释可能得出结论:不,没有保证。以下是
公开可用的草案关于
fgets
的说明:
char *fgets(char * restrict s, int n, FILE * restrict stream)
;
fgets
函数从指向stream
的流中最多读取n
个字符减一(保留换行符),并将其写入s
指向的数组中。在新行字符(保留)或文件结束后,不会再读取任何其他字符。在最后一个读入的字符之后立即写入空字符。
如果成功,fgets
函数返回s
。如果遇到文件结束并且没有将任何字符读入数组,则数组内容保持不变,并返回空指针。如果操作期间发生读取错误,则数组内容未定,并返回空指针。
对于它应该从输入中读取多少内容有保证,即在换行符或EOF处停止读取,并且不要读取超过
n-1
字节。虽然没有明确说明可以向缓冲区中写入多少内容,但是通常认为
fgets
的参数
n
用于防止缓冲区溢出。标准使用模糊的术语“读取”,这可能并不一定意味着
gets
不能向缓冲区中写入超过
n
个字节,如果您想在术语上挑剔的话。但请注意,相同的“读取”术语用于两个问题:限制
n
和EOF /换行符。因此,如果您将与
n
相关的“读取”解释为缓冲区写入限制,则[为了保持一致性]您可以/应该将其他“读取”也解释为同样的方式,即当字符串比缓冲区短时不写入更多内容。
另一方面,如果您区分短语动词“read into”(=“write”)和仅“read”的用法,那么您不能像读取其他文本那样读取委员会的文本。您可以保证它不会将更多的
n
字节“read into”(=“write to”)数组,但是如果输入字符串由于换行符或EOF而提前终止,则只保证其余部分(输入)不会被“read”,但是不确定这是否意味着它们不会被“read into”(=“written to”)缓冲区在这种更严格的阅读下。关键问题是关键字是“into”,该关键字已省略,因此问题是我在以下修改的引用中给出的完成是否是预期的解释:
在新行字符(保留)或文件结束后不会再读取任何其他字符[到数组]中。
坦白地说,一个作为公式陈述的单个
后置条件(在这种情况下可能非常简短)比我引用的措辞更有帮助...
我懒得尝试分析他们关于
*scanf
系列的写作方式,因为我怀疑考虑到这些函数中发生的所有其他事情,它可能会更加复杂。他们关于
fscanf
的写作方式大约有五页长... 但是我怀疑类似的逻辑也适用。