我正在尝试覆盖文件中仅包含无符号长数字的一行。 该文件的内容如下所示:
1
2
3
4
5
我想用数字 0 替换特定数字。我编写的代码如下所示:
FILE *f = fopen("timestamps", "r+");
unsigned long times = 0;
int pos = 0;
while(fscanf(f, "%lu\n", ×) != EOF)
{
if(times == 3)
{
fseek(f, pos, SEEK_SET);
fprintf(f, "%lu\n", 0);
}
times = 0;
pos = ftell(f);
}
fclose(f);
f = fopen("timestamps", "r");
times = 0;
while(fscanf(f, "%lu\n", ×) != EOF)
{
printf("%lu\n", times);
times = 0;
}
fclose(f);
程序的输出如下所示:
1
2
10
5
有趣的是,如果我 cat 文件,它看起来像这样:
1
2
10
5
我是不是在我的ftell
中犯了错误?另外,为什么 printf
没有显示 cat
显示的缺失行?
最佳答案
我可以复制和修复。
当前的问题是,当您在 r+
中打开文件时,每次从读取切换到写入时,您必须调用 fseek
并且从写作到阅读。
在这里,您在写入 0
之前正确地调用了 fseek
,但在写入和后续读取之后没有。文件指针未正确定位,您会得到未定义的行为。
修复很简单,只需替换:
if(times == 3)
{
fseek(f, pos, SEEK_SET);
fprintf(f, "%lu\n", 0);
}
与
if(times == 3)
{
fseek(f, pos, SEEK_SET);
fprintf(f, "%lu\n", 0);
pos = ftell(f);
fseek(f, pos, SEEK_SET);
}
但是注意:它在这里起作用是因为您用完全相同长度的线替换了线。如果您尝试用包含 0 的行替换包含 1000 的行,您将在行尾为 \r\n
的 Windows 系统上得到包含 0
的额外行,并且00
在类似 unix 的系统上,行尾为 \n
。
因为这是会发生的事情(Windows 情况):
重写前:
... 1 0 0 0 \r \n ...
之后:
... 0 \r \n 0 \r \n ...
因为顺序文件是......一个字节的顺序系列!
关于c - 覆盖文件中的一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29875239/