13

我希望使用“a+b”模式打开一个文件,即如果它不存在它会自动创建,但如果它存在我不想覆盖它。我希望能够读取和写入文件。

该文件是二进制文件,我想在其中保存特定struct的记录。所以我想对我想要fseek()的记录做,然后使用fwrite().

代码如下所示(MyRecord是 atypedef到 a structFILENAME而是 a#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文件指针留在最后。对记录此行为的地方的任何引用表示赞赏(因为我找不到任何内容,或者我使用了错误的关键字)。

4

3 回答 3

20

那是因为在a模式下,写入FILE*总是附加到末尾。fseek仅在此模式下设置读指针。这记录在 C 标准7.19.5.3 fopen中:

使用附加模式('a'作为模式参数中的第一个字符)打开文件会导致所有后续对该文件的写入都被强制到当时的当前文件结尾,而不管对fseek函数的干预调用。

于 2011-04-03T20:51:06.017 回答
4

使用“r+b”模式,如果失败则回退到“w+b”。

“a+b”模式,允许你阅读和追加;"r+b" 允许随机读写。

的文档fopen描述了文件在不同模式下的行为方式。

于 2011-04-03T20:46:45.050 回答
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 /* ... */
于 2011-04-03T21:11:19.110 回答