提问人:Fraser Orr 提问时间:11/8/2023 更新时间:11/8/2023 访问量:96
在 C 语言中使用 fseek 随机访问文件
Random access of a file with fseek in C
问:
我正在尝试在现有文件的中间写入一些数据,但是,目前尚不清楚使用哪种模式打开。如果我用“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。
关于如何实现这一点的任何建议?
答:
当您在“追加”模式下打开文件时,所有写入都会在文件末尾进行。
MSVC文档说:
使用访问类型或访问类型打开文件时,所有写入操作都发生在文件末尾。可以使用 或 重新定位文件指针,但在执行任何写入操作之前,始终将指针移回文件末尾。因此,无法覆盖现有数据。
"a"
"a+"
fseek
rewind
若要打开现有文件进行读取和写入,请使用该模式。"r+"
评论
fseek
我希望测试文件 ttt 包含“12xxx67890”,但它包含“1234567890xxx”。(fseek 的结果为 0。
fseek()
不是问题。您仍然可以使用它重新定位指针,但每次在追加模式下写入都会将其设置为指向文件的末尾。
cppreference - fopen, fopen_s:
在追加文件访问模式下,无论文件位置指示器的当前位置如何,数据都会写入文件末尾。
在 append 模式下的 fseek()
上查看这个问题。在用于读取文件和写入文件时,此行为非常有用。"a+"
要解决此问题,您可以使用 读取扩展模式 。这使您可以读取和写入文件,而无需关闭并重新打开它。"r+"
cppreference - fopen, fopen_s:
In update mode (), both input and output may be performed, but output cannot be followed by input without an intervening call to
fflush
,fseek
,fsetpos
orrewind
, and input cannot be followed by output without an intervening call tofseek
,fsetpos
orrewind
, unless the input operation encountered end of file. In update mode, implementations are permitted to use binary mode even when text mode is specified.'+'
A working solution might look like this:
#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;
}
You could now be tempted to just use once at the start of your program since it can be used to perform both write actions you use but note that it will not create a new file if it does not exists yet."r+"
评论
"r+"
r+
rb+
b
ftell