我试图在现有文件的中间写入一些数据,但是,不清楚该用什么模式打开。如果我用“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。)
对于如何实现这一点有什么建议吗?
2条答案
按热度按时间btxsgosb1#
我希望测试文件ttt包含“12xxx67890”,但它包含“1234567890xxx”。(fseek的结果是0。)
fseek()
不是问题所在。你仍然可以用它来重新定位指针,但是在追加模式下的每次写入都会将它设置为指向文件的末尾。cppreference - fopen, fopen_s:
在附加文件访问模式下,数据被写入文件的末尾,而不管文件位置指示符的当前位置。
请参阅
fseek()
在附加模式下的this问题。当使用"a+"
从文件中读取和写入时,此行为可能很有用。要解决这个问题,你可以使用读取扩展模式
"r+"
。这允许你读取和写入文件,而不必关闭和重新打开它。cppreference - fopen, fopen_s:
在更新模式下(
'+'
),可以执行输入和输出两者,但是在没有对fflush
、fseek
、fsetpos
或rewind
的中间调用的情况下,输出不能被输入跟随,并且在没有对fseek
、fsetpos
或rewind
的中间调用的情况下,输入不能被输出跟随,除非输入操作遇到文件结束。在更新模式下,即使指定了文本模式,也允许实现使用二进制模式。一个可行的解决方案可能看起来像这样:
字符串
现在你可能想在程序开始时只使用
"r+"
一次,因为它可以用来执行你使用的两个写操作,但请注意,如果它不存在,它不会创建一个新文件。disbfnqx2#
当你在“append”模式下打开一个文件时,所有的写操作都发生在文件的末尾。
MSVC documentation说:
当使用
"a"
或"a+"
访问类型打开文件时,所有的写操作都发生在文件的末尾。使用fseek
或rewind
可以重新定位文件指针,但在执行任何写操作之前,文件指针总是被移回文件的末尾。因此,现有数据不能被覆盖。要打开现有文件进行阅读和写入,请使用
"r+"
模式。