除非我使用fseek(fp,0,SEEK_CUR),为什么在rb +模式下R / W转换中间文件失败?为什么它在文件末尾有用?

时间:2013-05-24 05:32:34

标签: c buffer flush fseek

我从来没有意识到这一点。我可以下意识地假设我可以在现有文件的读取和写入之间转换打开更新模式,就像那样。但是关于SO的两个问题({{3 }},1)让我持怀疑态度,我决定尝试一下。这就是我找到的:

在第一个程序prog1中,我处理的文件source.txt只有行致命武器。我读了第一个世界致命使用fscanf()并打算在致命步枪之后写“步枪”。但它只是失败了,我仍然得到原始内容在写操作结束时致命武器。但是在第一个程序中,如果我插入行fseek(fp,0,SEEK_CUR),写操作正常,我得到致命步枪。我注意到fseek(fp,0,SEEK_CUR)只是为了它而没有用于调用fseek()之外的其他目的,因为根本没有网络搜索。

但是在第二个程序prog2中,相同的场景不需要fseek(fp,0,SEEK_CUR)语句。确切地说,在第二个程序中,与第一个程序中读取文件的中间部分相反。程序,在这里我读到文件的末尾,然后开始写在那里。即使没有使用fseek(fp,0,SEEK_CUR),写得很成功,我得到了所需的内容致命武器销售

问题:为什么我们无法在文件中间从read转换为write模式,以及fseek(fp,0,SEEK_CUR)使其工作的差异?与此同时,如果我们读到文件结尾并写在那里,为什么同样的转换工作没有任何大惊小怪?为什么在第二种情况下不需要fseek(fp,0,SEEK_CUR)?我使用fseek(fp,0,SEEK_CUR)的建议是多么可取在第一个程序中使写入成功?有更好的选择吗?

关于SO的两个问题似乎在某种程度上解决了同一个问题,但由于它们更多地基于寻求文本/书籍摘录的解释,所以面向它们的答案似乎并没有解决我想要知道的问题准确地说。

//PROG1

#include <stdio.h>

int main ()
{
    FILE *fp=fopen("D:\\source.txt","r+");
    char arr[20],brr[50];
    fscanf(fp,"%s",arr);
    printf("String is %s\n",arr);
    //fseek(fp,0,SEEK_CUR);  //Doesn't work without it
    fprintf(fp," musket");
    rewind(fp);
    fgets(brr,50,fp);
    printf("New string is %s",brr);
    fclose(fp);
}

输出:

1)没有fseek() - 致命武器

2) fseek() - 致命步枪

//PROG2    

#include <stdio.h>

int main ()
{
    FILE *fp=fopen("D:\\source.txt","r+");
    char arr[20],brr[50];
    fgets(arr,20,fp);
    printf("Initial line is %s\n",arr);
    fprintf(fp," sale"); //writes to end of file
    rewind(fp);
    printf("New string is %s",fgets(brr,50,fp));
    fclose(fp);
}

没有fseek()的输出: - Lethal weapon sale

1 个答案:

答案 0 :(得分:0)

实际上,它看起来像是libc实现中的一个错误。 文件I / O流通常是由OS内核实现的基于文件描述符的二进制I / O的libc抽象。所以任何奇怪的行为都应归咎于你特定的libc怪癖。

由于您显然使用的是Windows,这可能是您遇到问题的根源。你正在使用什么编译器? 在Ubuntu 11.10上,GCC 4.6.1和glibc-2.13没有这样的问题。