fgets似乎导致写入文件

时间:2015-02-05 19:22:03

标签: c

在尝试使用一段Python代码帮助某人之后,我运行了以下测试;我知道测试很简单,但我无法弄清楚为什么会发生这种情况。

基本思路是:我有以下C代码:

#include <stdlib.h>
#include <stdio.h>

int main() {
    FILE *pf = fopen("test.txt", "r+");
    char buf[100];
    fgets(buf, 100, pf);
    fseek(pf, -7, SEEK_CUR);
    fwrite("0", 1, 1, pf);
    //NEXT LINE PROBLEMATIC
    fgets(buf, 100, pf);
    fclose(pf);
    return 0;
}

和包含一行的输入文件: ABCDEFGHIJKLMNOPQRSTUVWXYZ

我希望输出在字符串中包含零;然而,这发生了: abcdefghijklmnopqrs0bcdefghijklmnopqrstuvwxyz

(文本后面有多个空格字符)。如果我注释掉有问题的行(第二次调用fgets),则输出按预期工作。

有人知道为什么会这样吗?

对我而言,由于行尾后的空格字符,它似乎是缓冲区溢出;使用cl.exe而不是gcc进行复制我得到了这个: abcdefghijklmnopqrs0bcdefghijklmnopqrstuvwxyzt e s t e \ p y _ w e d t t。 t x t c l e; i - ] h&amp; ^ u a

所以这肯定是一个溢出造成的,最有可能是通过调用fseek / fwrite来调用fgets。

2 个答案:

答案 0 :(得分:0)

如果有人发现这个,那么上午的建议是正确的,我不知道为什么我第一次搜索时找不到它。请在此处查看答案:why fseek or fflush is always required between reading and writing in the read/write "+" modes

有声望更高的人,请标记为副本并关闭:)

答案 1 :(得分:-1)

没有什么超自然的......

这将读取26个字母字符,当前偏移量将设置为26:

fgets(buf, 100, pf);

这将当前偏移设置为19,因此指向字母t的第20个字符:

fseek(pf, -7, SEEK_CUR);

然后将0写在t上,并将偏移量设置为20:

fwrite("0", 1, 1, pf);

这将读取buf中剩余的字符uvwxyz并将偏移量设置为26:     fgets(buf,100,pf);

所以最后你会在文件中有abcdefghijklmnopqrs0uvwxyz

缓冲区中的内容是上次读取的内容,必须是uvwxyz(文件的六个最后一个字符,毫无疑问),因为没有修改它们,每次打开只有一个偏移量文件。