fgetpos/fsetpos和ftell/fseek有什么区别

car*_*ips 29 c c-standard-library

What's the difference between using the functions fgetpos() and fsetpos() and using the functions ftell() and fseek() to get and set a position in a file?

What are fgetpos() and fsetpos() good for? Why would they be used instead of ftell() and fseek()?

Hug*_*otl 22

上述答案都不正确 - 事实上,如果您可以fsetpos互换使用fseek,则可能会引入安全漏洞(https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=20087255).

原因是fpos_t *pos参数to fsetpos实际上不是一个整数,所以它不能用于寻找文件中的任意位置.因此,唯一有效的值是从中获得的值fgetpos.正如文档所说,

与流相关联的内部文件位置指示符被设置为由表示的位置,该位置pos是指向其值应先前通过调用获得fpos_t对象指针.fgetpos

(http://www.cplusplus.com/reference/cstdio/fsetpos/)

如果你想要的是能够寻找超出32位边界的任意位置,那么使用ftello/ fseeko和编译#define _FILE_OFFSET_BITS 64.


car*_*ips 17

好吧,从联机帮助页我们可以看到ftell和fseek使用类型long int来表示文件中的偏移量(位置),因此可能限于可以用long int表示的偏移量.(类型long int不保证保持大于2**31-1的值,将最大偏移限制为2千兆字节).另一方面,较新的fgetpos和fsetpos函数使用特殊的typedef(fpos_t)来表示偏移量.这个typedef背后的类型,如果选择得当,可以代表任意大的偏移量,因此fgetpos和fsetpos可以用于任意大的文件.fgetpos和fsetpos还记录与多字节流相关联的状态.

  • **这个答案是不正确的!**如果你只是想要超越'2**31-1`,那就是`fseeko`.正确的答案是`fgetpos`只能寻找先前由`fgetpos`获得的位置,并且`fpos_t`**不能被**解释为整数,正如手册页所说:*在某些非UNIX系统,**fpos_t对象可能是一个复杂的对象**,这些例程可能是可移植地重新定位文本流的唯一方法.* (8认同)
  • 答案不是不正确但不充分.它正确地说明了`fseek`和朋友的限制,它正确地说'fgetpos`和朋友是没有这种限制的选项.上面的答案永远不会说你可以混合`fseek`和`fsetpos`和firends,这确实很危险.此外,它永远不会声明`fpos_t`是一个整数类型.相反,Mecki建议`fseeko`和firends是非ISO-C标准函数(但POSIX函数). (2认同)

小智 6

fgetpos() 与 fsetpos() 配合使用。ftell() 与 fseek() 配合使用。

fgetpos() 看起来实际上很像 ftell(),因为两者都采用 FILE* 参数,并且都返回文件中的某种位置,尽管风格略有不同。但请注意:只有 fseek() 允许您从文件开头、文件中当前位置以及从文件末尾向后查找(fseek() 的第三个参数是 SEEK_SET、SEEK_CUR 和 SEEK_END )。fsetpos() 不执行此操作。fsetpos() 仅限于返回到从 fgetpos() 获得的某个位置。

假设您想将文件读入内存。malloc() 需要多少堆?您需要文件的大小。尽管某些 C 编译器可能会添加非标准函数,但我尚未在 C 标准库中找到任何可以告诉您文件大小的函数。例如,Borland Turbo C 有 filelength()。但我还没有在标准 C 库中看到 filelength() 。

因此,您可以使用 fseek() 在文件末尾之前查找 0 个字节。然后使用 ftell() 获取以字节为单位的位置,并以此为基础计算堆内存量。

您还可以做什么来获取文件大小?您可以使用 fgetc() 读取每个字符,计数直到到达末尾。但我认为使用 fseek() 和 ftell() 更好、更容易。