提问人:osmangokalp 提问时间:5/14/2023 最后编辑:Solomon Uckoosmangokalp 更新时间:5/16/2023 访问量:2394
带有 SEEK_CUR 的 fseek() 函数中的零偏移有什么用?
What is the use of zero offset in fseek() function with SEEK_CUR?
问:
while (fread(&product, sizeof(Product), 1, file) == 1) {
product.price *= 2.0;
fseek(file, -sizeof(Product), SEEK_CUR);
fwrite(&product, sizeof(Product), 1, file);
fseek(file, 0, SEEK_CUR);
}
使用上面的代码,我试图将二进制文件中每个产品的价格翻倍,其中每条记录都是 Product 结构的一个实例。当我运行此代码时,它正确更新了文件中的所有价格。
据我所知,自动将文件指针移动到下一条记录。使用 first ,代码将文件指针移回记录的开头。然后它使用 更新它。 自动将文件指针移动到下一条记录。在 while 循环中,应继续读取下一条记录,依此类推。fread
fseek
fwrite
fwrite
fread
这里似乎没有必要。但是,如果我删除它,代码会进入无限循环。我不明白为什么会这样。fseek(file, 0, SEEK_CUR);
我试图使用 .但是我没有看到它的价值有任何变化。ftell
fseek(file, 0, SEEK_CUR);
答:
当打开流进行读取和写入时,不允许直接在读取和写入之间切换。ISO C11 标准的 §7.21.5.3 ¶7 规定如下:
当使用更新模式打开文件时(“+”作为上述模式参数值列表中的第二个或第三个字符),可以对关联的流执行输入和输出。但是,如果不干预调用 fflush 函数或文件定位函数(fseek、fsetpos 或 rewind),则输出不应直接跟在输入后面,除非输入操作遇到文件末尾。
如果删除该行
fseek(file, 0, SEEK_CUR);
然后,您的程序违反了此规则,这将调用未定义的行为。这意味着任何事情都可能发生,包括您的程序陷入无限循环的可能性。
评论
fseek(file, -sizeof(Product), SEEK_CUR);
fflush()
Product
char[]
fwrite()
fseek(file, 0, SEEK_CUR);
fflush(file);
一些执行随机寻道速度较慢的文件系统旨在通过使用单独的读写指针有效地处理对一系列记录的读-修改-写操作。像您这样的程序可能能够完全省略这些操作,前提是读取的数据量与写入的数据量相匹配,并且如果没有这些操作,它的运行速度可能比包含这些操作时运行得更快。fseek
fseek()
C 标准库实现需要跟踪对文件执行的最后一个操作是写入还是读取,以便相对可以相对于当前读取位置或当前写入位置进行操作,具体取决于上次执行的操作类型,但可以允许编写以利用双文件指针的程序在面向使用它们的系统时获得相关的性能提升。fseek()
尽管该标准可以将不进行干预的写入和读取行为归类为实现定义,但这将被视为意味着实现应尝试以一致的记录方式运行,即使针对具有并不总是可预测的极端情况行为的平台。fseek()
评论
fwrite()
fseek().