如果在“a + b”模式下打开文件指针,fseek()会将文件指针移动到文件的开头吗?
我希望使用“a + b”模式打开一个文件,即如果它不存在则会自动创建,但如果是,我不想覆盖它。 我希望能够读取和写入该文件。
该文件是二进制文件,我想在其中保存特定struct
记录。 所以我想对我想要的记录执行fseek()
,然后使用fwrite()
保存记录。
代码如下所示( MyRecord
是struct
的typedef
,而FILENAME
是文件名的#define
):
int saveRecord(MyRecord *pRecord, int pos) { FILE* file = fopen(FILENAME, "a+b"); if (file == NULL) { printf("Unable to open file %s\n", FILENAME); return 0; } fseek(file, pos * sizeof(MyRecord), SEEK_SET); fwrite(pRecord, sizeof(MyRecord), 1, file); fclose(file); return 1; }
但是这个代码只是将记录追加到文件的末尾,即使我将pos
设置为0.为什么SEEK_SET
模式下SEEK_SET
不能使用fseek()
?
我知道我可以简单地用“r + b”打开它,如果它失败了用“wb”打开它,但我想知道为什么这不起作用以及为什么用SEEK_SET
fseek()
将文件指针留在最后。 对记录此行为的地方的任何引用都赞赏(因为我找不到任何内容,或者我使用了错误的关键字)。
那是因为在a
模式下,写入FILE*
总是追加到最后。 fseek
仅在此模式下设置读指针。 这在C标准7.19.5.3 fopen中有记载 :
打开具有追加模式的文件(
'a'
作为mode参数中的第一个字符)会导致对文件的所有后续写入强制转换为当前的文件结束,而不管是对fseek
函数的中间调用。
普通C没有任何理智的方式来实现你想要的。 如果你在POSIX系统或远程关闭的任何东西,你可以使用fd=open(FILENAME, O_CREAT|O_RDRW, 0666)
然后使用fdopen(fd, "rb+")
。
编辑:你可以尝试另一件事,用普通的C:
f = fopen(FILENAME, "a+b"); if (!f) /* ... */ tmp = freopen(0, "r+b", f); if (tmp) f = tmp; else /* ... */
如果失败,请使用“r + b”模式并回退到“w + b”。
“a + b”模式,允许您阅读和追加; “r + b”允许随机读写。
fopen
的文档描述了文件在不同模式下的行为方式。