对于文本流,偏移量应为零,或者offset应为先前成功调用与同一文件关联的流上的ftell函数返回的值,并且应为SEEK_SET .
我知道 offset
必须是 ftell
函数的retun值,或者0, whence
必须是 SEET_SET
(或0) . 但我使用了一些整数作为偏移和不同的 SEEK_...
它似乎运作良好 .
例如,这些工作:
fseek(file, 4, SEEK_CUR);
fseek(file, -1, SEEK_END);
fseek(file, 0, SEEK_CUR);
当我阅读规范时,在我看来它应该不起作用 . 我试过这种方式多次使用fseek,它从未失败过 . 它为什么有效,我没有得到什么?
5 回答
规范说明了必须工作的内容 . 它应该被视为创建c库的人的最低要求(即
fseek
等人的实现者) .使用不正确可能仍然有效,但无法保证 . 结果取决于平台 .
例如,
fseek
的Linux手册页说:您可以看到,您尝试过的内容将在Linux中用于文本和二进制流 . 但是,可能存在
fseek
不能与SEEK_CUR或SEEK_END一起用于文本流的平台 .还要注意,流可以与不同的东西相关联:文件,键盘,套接字,终端窗口,设备等 .
在ftell文档中,您可以阅读
你引用的意思是如果你知道你想把指针放在哪里就可以使用它,你可能知道它,因为在优先级中你调用了ftell() .
您对fseek的所有调用都是有效的,但在文本文件中使用fseek进行移动没有太大意义,因为它不是随机访问(二进制)文件,但这并不意味着使用它是错误的 .
对于文本文件,您可以找到here最常用的访问它的函数,如fscanf(),fprintf()等 .
您的所有
fseek
电话都有效 . 您作为第二个参数提供的数字是偏移量,这意味着它相对于您提供的搜索类型作为第三个参数 .但另请参阅用户Tu.ma的解释,如果文件已在文本模式下打开(特别是在Windows下由于回车/换行翻译),搜索位置不准确和/或无意义 .
没有什么可以阻止你使用fseek超越文件的当前大小 . 因为这样做可以让你在那时写入数据,填补与NUL之间尚未写入的差距 . 与此示例代码一样 - 它创建一个包含1000个NUL的文件然后
"hello\n"
我认为
fseek
的定义与C标准一样的主要原因是文本文件中的逻辑位置可能与文本文件开头的物理字节数无关 .例如,在Windows实现中,将磁盘上的文件中的
\r\n
转换为\n
以保持与Unix行结尾的兼容性并不罕见 . 所以如果你的文件是这样的:即两行,你
fseek
到位置6,你期望在\n
或w
?如果您试图通过在Windows上使用fgetc
来查找字符数,那么您可以假设您将使用w
. 但是fseek
可能会在不扫描行结尾的情况下前进到字节6 .Edit
是 . 问题出在"character"的定义中 . 如果您所在的环境使用DOS约定,则当接下来的两个字节为
0x0d 0x0a
时,在文本流上使用fgetc
将文件位置提前2,但仅返回0x0a
. 实现可能会进行其他转换,例如将分解的Unicode转换为预合成的unicode,反之亦然 .C标准中的措辞允许实现丢失文件中的字节与
fgetc
返回的字符之间的一对一映射,而不必过度复杂化fseek
.