osm*_*alp 49 c io file fseek language-lawyer
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);
}
Run Code Online (Sandbox Code Playgroud)
使用上面的代码,我尝试将二进制文件中每个产品的价格加倍,其中每个记录都是 Product 结构的实例。当我运行此代码时,它正确更新了文件中的所有价格。
据我所知,fread自动将文件指针移动到下一条记录。使用第一个fseek,代码将文件指针移回到记录的开头。然后它使用 更新它fwrite。fwrite自动将文件指针移动到下一条记录。在while循环中,fread应该继续读取下一条记录,以此类推。
这里似乎fseek(file, 0, SEEK_CUR);没有必要。但是,如果我删除它,代码就会进入无限循环。我不明白为什么会发生这种情况。
我尝试使用 观察文件指针的值ftell。但我没有看到它的值有任何变化fseek(file, 0, SEEK_CUR);。
And*_*zel 67
当一个流同时打开用于读取和写入时,不允许直接在读取和写入之间切换。ISO C11 标准的 \xc2\xa77.21.5.3 \xc2\xb67规定如下:
\n\n\n当使用更新模式打开文件时(\'+\' 作为上述模式参数值列表中的第二个或第三个字符),可以在关联的流上执行输入和输出。但是,如果没有对 fflush 函数或文件定位函数(fseek、fsetpos 或 rewind)的中间调用,输出后面不得直接跟有输入,并且在没有对文件定位的中间调用的情况下,输入后面不得直接跟有输出函数,除非输入操作遇到文件结尾。
\n
如果删除该行
\nfseek(file, 0, SEEK_CUR);\nRun Code Online (Sandbox Code Playgroud)\n那么你的程序违反了这个规则,这会调用未定义的行为。这意味着任何事情都可能发生,其中包括您的程序陷入无限循环的可能性。
\n一些执行随机查找速度相当慢的文件系统被设计为允许通过使用单独的读和写指针来有效地处理对记录序列的读-修改-写操作。fseek如果读取的数据量与写入的数据量相匹配,像您这样的程序可能能够完全省略这些操作,并且在没有fseek()这些操作的情况下运行的速度可能比包含这些操作时运行的速度快得多。
AC 标准库实现需要跟踪对文件执行的最后一个操作是写入还是读取,以便相对fseek()可以相对于当前读取位置或当前写入位置进行操作,具体取决于哪种类型操作是最后执行的,但可以允许为利用双文件指针而编写的程序在针对使用它们的系统时获得相关的性能增益。
尽管该标准可以将在没有干预的情况下进行写入和读取的行为归类fseek()为实现定义的行为,但这会被视为意味着实现应该尝试以一致的记录方式运行,即使针对具有极端情况行为的平台时也是如此。并不总是可预测的。
| 归档时间: |
|
| 查看次数: |
2486 次 |
| 最近记录: |