ftell() 在附加模式下返回的文件指针位置的初始值

initial value of file pointer position returned by ftell() in append mode

我正在查看 SO post fseek does not work when file is opened in "a" (append) mode,当我们在 [=14] 中打开文件时,我对由 ftell() 编辑的文件指针 return 的初始值有疑问=] 模式。 我尝试了下面的代码 file1.txt 包含数据 "Hello Welcome" 并在不同的地方打印了指针的位置。 最初 ftell() 将 return 位置 0。追加后,ftell() 将 return 最后一个位置。如果我们执行 fseek() 文件指针被更改,在这种情况下我移回 0 位置。 在附加模式下,我们无法读取数据。为什么指针最初在 0 位置?在追加模式下还有 fseek 的使用吗?

#include<stdio.h>
#include <string.h>
#include <errno.h>

#define MAX_BUF_SIZE 50

void readString(char* buffer,int maxSize)
{
    fgets(buffer,maxSize,stdin);
    // Note that if data is empty, strtok does not work. Use the other method instead.
    strtok(buffer,"\n");
}

extern int errno;

int main()
{
    FILE *fp1;
    char data[50];
    fp1=fopen("file1.txt","a");
    if(fp1==NULL)
    {
        // Print the error message
        fprintf(stderr,"%s\n",strerror(errno));
    }
    printf("Initial File pointer position in \"a\" mode = %ld\n",ftell(fp1));

    /* Initial file pointer position is 0 even in append mode
    As soon as data is write, FP points to the end.*/

    // Write some data at the end of the file only
    printf("\nEnter some data to be written to the file\n");
    readString(data,MAX_BUF_SIZE);
    // The data will be appended
    fputs(data,fp1);

    // File pointer points to the end after write operation
    printf("File pointer position after write operation in append mode = %ld\n",ftell(fp1));

    fseek(fp1,0,SEEK_SET);
    printf("File pointer position after fseek in append mode = %ld\n",ftell(fp1));

    return(0);
}

Why the pointer is in 0 position initially?

这似乎是特定于实现的细节。我在 C 标准中找不到专门提到以纯追加模式打开的文件的初始文件偏移量的参考资料。

Also is there any use of fseek in append mode?

在纯追加模式下,无法读取,fseek() 似乎毫无用处。根据 7.21.5.3 fopen 函数 the C standard 的第 6 段:

Opening a file with append mode ('a' as the first character in the mode argument) causes all subsequent writes to the file to be forced to the then current end-of-file, regardless of intervening calls to the fseek function. ...

然而,根据第 7 段,以 append/update 模式打开 "a+",对 fseek() 的调用可用于定位当前文件指针以供读取:

When a file is opened with update mode ('+' as the second or third character in the above list of mode argument values), both input and output may be performed on the associated stream. ...

因此,fseek() 需要 以 append/update 模式从文件中读取,以便在写入其他内容后定位当前位置比当前文件结尾。

你问

Why the pointer is in 0 position initially?

在您提出的一般性级别上唯一可用的答案,因为它是由您的特定实现做出的选择。标准说:

If a file can support positioning requests (such as a disk file, as opposed to a terminal), then a file position indicator associated with the stream is positioned at the start (character number zero) of the file, unless the file is opened with append mode in which case it is implementation-defined whether the file position indicator is initially positioned at the beginning or the end of the file.

(C2011, 7.21.3/1)

因此,对于以附加模式打开的文件,实现可以选择将位置初始设置为文件的开头或末尾。前者与以任何其他模式打开文件时的行为一致,并反映下一次读取将发生的位置(对于允许读取的追加模式,例如"a+");后者反映了第一次写入的位置。我本人更喜欢前者,因为您不能依赖以追加模式打开的文件的文件位置来反映下一次写入的位置(该位置始终可以通过 fseek().[=17= 更改) ]

Also is there any use of fseek in append mode?

它的主要用途与以仅追加模式打开的文件无关。但是,我不准备说它 没有 用途,而且我当然不希望它仅仅因为将这样的文件传递给它而出错。该问题表明您对文件位置的概念有误。除了第一次打开文件时,它(对于支持它的流)只是该流上最后一个 I/O 操作产生的位置,其中 fseek() 真实的I/O操作。

当然,fseek() 在打开文件进行读取和追加的正常使用中是完全明智的。