C中使用fseek随机访问文件

2hh7jdfx  于 2023-11-16  发布在  其他
关注(0)|答案(2)|浏览(146)

我试图在现有文件的中间写入一些数据,但是,不清楚该用什么模式打开。如果我用“w”打开,它会截断文件,所以“a”似乎是显而易见的选择。我想做的是用“a”打开,然后查找到必要的位置。但是,当我这样做时,它总是写到结尾:

FILE* t = fopen("ttt", "w");
fprintf(t, "1234567890");
fclose(t);
t = fopen("ttt", "a");
int result = fseek(t, 2, SEEK_SET);
fprintf(stderr, "%d", result);
fprintf(t, "xxx");
fclose(t);

字符串
我希望测试文件ttt包含“12xxx67890”,但它包含“1234567890xxx”。(fseek的结果是0。)
对于如何实现这一点有什么建议吗?

btxsgosb

btxsgosb1#

我希望测试文件ttt包含“12xxx67890”,但它包含“1234567890xxx”。(fseek的结果是0。)
fseek()不是问题所在。你仍然可以用它来重新定位指针,但是在追加模式下的每次写入都会将它设置为指向文件的末尾。
cppreference - fopen, fopen_s
在附加文件访问模式下,数据被写入文件的末尾,而不管文件位置指示符的当前位置。
请参阅fseek()在附加模式下的this问题。当使用"a+"从文件中读取和写入时,此行为可能很有用。
要解决这个问题,你可以使用读取扩展模式"r+"。这允许你读取和写入文件,而不必关闭和重新打开它。
cppreference - fopen, fopen_s
在更新模式下('+'),可以执行输入和输出两者,但是在没有对fflushfseekfsetposrewind的中间调用的情况下,输出不能被输入跟随,并且在没有对fseekfsetposrewind的中间调用的情况下,输入不能被输出跟随,除非输入操作遇到文件结束。在更新模式下,即使指定了文本模式,也允许实现使用二进制模式。
一个可行的解决方案可能看起来像这样:

#include <stdio.h>

int main() {
    FILE* t = fopen("ttt", "w");

    fprintf(t, "1234567890");
    fclose(t);

    t = fopen("ttt", "r+");
    int result = fseek(t, 2, SEEK_SET);

    fprintf(stderr, "%d", result);
    fprintf(t, "xxx");

    fclose(t);
    return 0;
}

字符串
现在你可能想在程序开始时只使用"r+"一次,因为它可以用来执行你使用的两个写操作,但请注意,如果它不存在,它不会创建一个新文件。

disbfnqx

disbfnqx2#

当你在“append”模式下打开一个文件时,所有的写操作都发生在文件的末尾。
MSVC documentation说:
当使用"a""a+"访问类型打开文件时,所有的写操作都发生在文件的末尾。使用fseekrewind可以重新定位文件指针,但在执行任何写操作之前,文件指针总是被移回文件的末尾。因此,现有数据不能被覆盖
要打开现有文件进行阅读和写入,请使用"r+"模式。

相关问题