在'a+'模式下打开一个文件

10
如果使用以下命令打开文件:
FILE *f1=fopen("test.dat","a+");

这里是需要翻译的内容:

man页面中写道:

a+

打开文件以供读取和追加(在文件末尾写入)。如果文件不存在,则创建该文件。用于读取的初始文件位置位于文件开头,但输出始终附加到文件末尾。

那么f1是否有两个单独的偏移指针,一个用于读取,另一个用于写入?

3个回答

20

不。

有一个指针,最初位于文件的开头,但当尝试进行写操作时,它会移动到文件的末尾。您可以使用fseekrewind将其重新定位到文件中的任何位置以供阅读,但写入操作会将其移回到文件末尾。


还有一个有用的信息是,在POSIX系统中,通常使用带有O_APPEND标志的“open”实现此操作:http://pubs.opengroup.org/onlinepubs/7908799/xsh/open.html - Daira Hopwood
如果在读取之前未调用fseek,则会在下面的代码中打印出许多空格。我本来希望屏幕上不会打印任何内容。但是为什么会打印空格呢?这意味着EOF没有被正确地遇到。如果取消下面的fseek的注释,数据将在屏幕上正确地打印出来。int main() { FILE *fp1; char ch; fp1=fopen("m.txt", "a+"); fputs("data appended", fp1); //fseek(fp1,0,SEEK_SET); while((ch=getc(fp1))!=EOF) { putc(ch,stdout); } fclose(fp1); return 0; } - Jon Wheelock

4

不,它只有一个指针。


4

在没有调用fseek的情况下,您永远不能混合使用FILE的读写操作。尽管在某些实现上可能按照您的意愿工作,但依赖此操作的程序具有未定义的行为。因此,拥有2个位置的问题是无意义的。


如果您看到支持POSIX文件操作的操作系统的C实现,并且stdio FILE操作不是简单的缓冲层而是具有其他定义行为的情况,那么请将其报告为该操作系统的错误。但是,如果没有这种情况出现,返回True。 - Daira Hopwood
@DairaHopwood:我对你想表达的意思感到困惑。在stdio上混合读写而没有中间的寻址问题纯粹是缓冲区的问题。这与文件描述符上的底层操作无关。 - R.. GitHub STOP HELPING ICE
我的意思是,如果stdio实现在这种情况下的未定义行为导致除更改缓冲数据写入位置之外的任何结果,则我认为其存在错误。也就是说,规范应该是生成的文件内容是实现定义的,而不是真正的未定义行为。否则,你会发现大量程序存在可利用的安全漏洞。 - Daira Hopwood
不,它没有漏洞。例如,一个非常好的实现方式是在调用者违反接口契约的情况下执行__asm__("hlt");或类似操作。但即使它破坏了内存,这仍然不是一个漏洞。漏洞存在于调用未定义行为的应用程序中。 - R.. GitHub STOP HELPING ICE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接