2016-08-02 73 views
11

功能如strcpy()malloc()strlen()和各种其他接受他们的观点或返回值作为size_t而不是intunsigned int原因是显而易见的。为什么fgets接受int而不是size_t?

某些文件函数如fread()fwrite()也使用size_t。通过扩展,预计char* fgets (char *str, int num, FILE *stream)应该使用size_t而不是int作为其缓冲区大小的参数。

但是,fgets()使用int。有什么客观的解释,为什么?

+12

C标准库没有一致性。功能随着时间的推移而发展。引入'fgets'时可能不存在'size_t'(只是我的猜测)。 – user694733

+1

https://groups.google.com/forum/#!topic/comp.std.c/FnENEIlCidg – artm

+3

歇斯底里的葡萄干。可能早期实现(标准化之前)使用'int'并且在C被标准化时继续进行“兼容性”。我正在投票结束*基于意见*。 –

回答

9

原来的K & R定义为fgets()在第155页上有int的说法。本书中介绍的代码也可以使用 和unsigned int(它使用>0,但是编写循环时永远不会低于零)。

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

应当注意的是,POSIX standard,这统一的UNIX的功能,在平行的开发是为了 ANSI C标准和issued late 1988。此标准已协调许多unix函数使用size_t,以便read()/write()现在 定义为size_t。但是对于C标准库函数,如fgets(),POSIX会优先C标准 (的当前版本标准的措辞):

此参考页上描述的功能与ISO C标准排列。 这里描述的要求和ISO C标准之间的任何冲突都是无意的。

所以在POSIX也,讽刺的是,fgets()仍然从它的历史ķ& [R int继承。


编辑:补充阅读

标准输入输出。h:该标题定义并原型化了K & R的第7章中列出的大多数功能。如果有的话,很少有改变在K & R中找到的 定义中,但添加了几个新功能。

+0

您是否有任何想法,当fgets的任何值得注意的C89之前的实现在传递负值时表现可预测性[例如,可预测地将其视为零,可以预测不做任何事情,读取-N字节的数据但省略换行符等等]?如果是这样,更改为size_t可能会禁止实现支持该功能,除非该长度限制为SIZE_T_MAX-UINT_MAX [从我所知道的情况来看,传递的长度大于缓冲区大小是定义的行为,前提是在结束之前成功读取换行符缓冲]。 – supercat

+1

K&R的实现日期从1978年开始。由于它是有符号整数,并且第一个循环条件是“--n> 0”,它将停止并将空终止符放入缓冲区。所以完全可以预测。如果参数是无符号的,则相同的代码可能会产生缓冲区溢出,但会在最大UINT_MAX迭代后停止(除非硬件会捕获符号位的翻转)。那么也可能有其他的实现:在89之前有很多编译器制造商,其中大多数现在不再被了解;-)。 – Christophe

+0

@supercat我可以找到我以前的莱迪思C编译器1986年([由微软收购](https://en.wikipedia.org/wiki/Lattice_C))与其标准库的来源。 'fgets()'是用'for(i = 0; i Christophe

相关问题