为什么fgets接受int而不是size_t?

use*_*000 11 c size-t language-lawyer

功能如strcpy(),malloc(),strlen()和各种人接受他们的观点或作为返回值size_t,而不是一个int或一个unsigned int显而易见的原因.

一些文件功能,如fread()fwrite()使用size_t.通过扩展,可以预期char* fgets (char *str, int num, FILE *stream)应该使用a size_t而不是intas作为其缓冲区大小的参数.

但是,fgets()用一个int.有客观解释为什么?

Chr*_*phe 9

原始的K&R fgets()在第155页定义了一个int参数.书中提供的代码unsigned int也可以使用(它使用a >0,但是循环被编写为永远不会低于零).

size_t稍后介绍,在C89(ANSI C)中作为类型sizeof().由于此功能是为协调内存分配而专门引入的,因此内存管理功能和字符串功能也相应更新.但是文件I/O不是:size_tC89中使用的唯一文件函数是C89引入的新函数,并且在K&R中不存在,例如fread()/ fwrite().是的,K&R没有这些功能,仅依靠使用文件描述符的(非便携式)unix读/写功能进行块操作.

应当指出的是,POSIX标准,已经统一了UNIX功能,在平行于ANSI C标准的开发和发行的1988年年底.该标准已经统一了许多unix函数,size_t以便read()/ write()现在定义size_t.但是对于C标准库函数,例如fgets(),POSIX优先于C标准(当前版本标准的措辞):

此参考页面上描述的功能与ISO C标准一致.此处描述的要求与ISO C标准之间的任何冲突都是无意的.

所以在POSIX中,具有讽刺意味的是,它fgets()仍然继承了其历史悠久的K&R int.


编辑:额外阅读

stdio.h: 此标头定义并原型化了K&R第7章中列出的大多数功能.K&R中的定义几乎没有任何变化,但增加了几个新功能.

  • 如果该值大于缓冲区的大小,但是在缓冲区溢出之前收到换行符,是否会将行为定义为将数据读取到换行符?如果,那么,这意味着如果`size`被改为`size_t`,那么`fgets(buff,-1,file)`将具有与预先存在的行为不同的*定义*行为.标准的作者不反对将在不同实现中以各种方式定义的事物标记为未定义行为,因为他们认为不会阻止任何人继续支持...... (2认同)
  • ......已经在使用的有用行为[这种期望在整个二十世纪都存在,但后来受到了攻击],但不愿意定义任何实现可能以相反方式定义的行为. (2认同)