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

问题描述 投票:0回答:1

我从来没有意识到这一点。我可以很好地在潜意识中假设我可以在现有文件上的读写之间进行转换,打开它的更新模式,就像这样。但关于 Stack Overflow 的两个问题(12)让我持怀疑态度,我决定尝试一下。这是我发现的:

在第一个程序

prog1
中,我处理一个文件
source.txt
,其中只有行致命武器。我使用fscanf()阅读了第一个世界
Lethal
,并打算在那之后写下“步枪”,希望得到Lethal步枪。但它只是失败了,并且在写入操作结束时我仍然得到原始内容Lethal Weapon

但是在第一个程序中,如果我插入行

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)
来使第一个程序中的写入成功有多明智?有更好的选择吗?

Stack Overflow 上的两个问题似乎在某种程度上解决了同一问题,但由于它们更多地基于寻求文本/书籍摘录的解释,因此针对它们的答案似乎并没有解决我想知道的内容精确的术语。

// PROG 1

#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);  // It 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()
-- 致命步枪

// PROG 2

#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

c buffer flush fseek
1个回答
0
投票

实际上,它看起来像是您的 libc 实现中的一个错误。 文件 I/O 流通常是操作系统内核实现的基于文件描述符的二进制 I/O 的 libc 抽象。因此,任何奇怪的行为都应归因于您特定的 libc 怪癖。

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

© www.soinside.com 2019 - 2024. All rights reserved.