c - 覆盖文件中的一行

标签 c

我正在尝试覆盖文件中仅包含无符号长数字的一行。 该文件的内容如下所示:

1
2
3
4
5

我想用数字 0 替换特定数字。我编写的代码如下所示:

FILE *f = fopen("timestamps", "r+");

unsigned long times = 0;
int pos = 0;
while(fscanf(f, "%lu\n", &times) != 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", &times) != 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/

相关文章:

c - getchar() 和标准输入

C语言十六进制转二进制

c++ - VC/C++裸属性有什么作用?

c++ - 常量函数参数作为静态数组大小?

c++ - 默认堆栈大小

检查数字是否为右截素数

Visual Studio 的 C99 复杂支持

c - scanf两个整数输入,当第一个输入是某个数字并按下回车键时中断?

无法理解 strtok 和 sscanf 的这种行为

c - Valgrind 在检查内存泄漏时可能丢失消息 - C