我希望使用“a + b”模式打开文件,即如果它不存在则会自动创建,但如果是,我不想覆盖它。我希望能够读取和写入文件。
该文件是二进制文件,我想在其中保存特定struct
的记录。所以我想对我想要的记录fseek()
,然后使用fwrite()
保存记录。
代码如下所示(MyRecord
是typedef
到struct
,而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,此代码也会将记录追加到文件的末尾。为什么fseek()
SEEK_SET
不能在附加模式下工作?
我知道我可以简单地用“r + b”打开它,如果失败则用“wb”打开它,但我想知道为什么这不起作用以及为什么fseek()
与SEEK_SET
将文件指针留在最后。对记录此行为的地方的任何引用都赞赏(因为我找不到任何内容,或者我使用了错误的关键字)。
答案 0 :(得分:18)
这是因为在a
模式下,写入FILE*
始终追加到最后。 fseek
仅在此模式下设置读指针。这在C标准中有记录, 7.19.5.3 fopen :
使用追加模式打开文件(
'a'
作为mode参数中的第一个字符) 导致对文件的所有后续写入被强制转换为当前的文件结束, 无论是对fseek
函数的干预调用。
答案 1 :(得分:4)
答案 2 :(得分:4)
普通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 /* ... */