传递给函数时,文件指针的行为会有所不同。 为什么?

所以我有这个代码

void getdata(int *q) { for(int i=0;i<3;++i) scanf("%d",q++); *q=10; } int main() { int *p,a[4]; p=a; getdata(p); printf("%d",*p); return 0; } 

而且输出很明显。

 7 8 9 7 

但文件指针不能以相同的方式工作。 我试图编写一个基本代码,用于将数据附加到文件中。

 void getdata(FILE *fp) { char ch; while((ch=getchar())!=EOF) fputc(ch,fp); rewind(fp); } void printdata(FILE *fp) { char ch; while((ch=fgetc(fp))!=EOF) putc(ch,stdout); } int main() { FILE *fp1; fp1=fopen("music.txt","w+"); getdata(fp1); printf("Text is::\n"); printdata(fp1); fp1=fopen("music.txt","a+"); printf("\nEnter some more text::\n"); getdata(fp1); printf("\nAfter appending text is::\n"); printdata(fp1); return 0; } 

这段代码工作正常。 但如果rewind(fp); 被删除它行为怪异。 为什么我需要倒回指针? 虽然指向同一个文件的函数不是fp1fp本地的,所以不应该像第一个程序那样相互影响?

让我们看一下FILE结构可能非常简化的实现。 出于示例的目的,假设content指向映射到磁盘上文件的内存。

 typedef struct FILE { size_t size; size_t cursor; uint8_t *content; } FILE; int fputc(FILE *f, char c) { size++; return f->content[f->cursor++] = c; } int fgetc(FILE *f) { return (f->cursor == f->size) ? EOF : f->content[f->cursor++]; } void rewind(FILE *f) { f->cursor = 0; } 

现在,当您调用这些函数时,很明显它们会修改底层对象。 完成写入文件后,光标指向最后一个元素,因此如果不rewindfgetc将立即返回EOF。


为了澄清,当你调用fopen你创建了一个存储在某个地方的FILE对象。 您无法控制此对象,只需获取指向它的指针即可。 如果更容易理解,可以将此指针(在您的示例中为fp1 )视为文件ID。 任何更改都在FILE对象上完成,而不是指针/ ID本身。

在此处输入图像描述 打开文件的任何进程都有一个数据结构,用于存储与文件相关的搜索位置等。 无论你打开同一个文件多少次,它都是指向同一个DS的指针。 打印两个文件指针的值应该是相同的……所以你访问文件的文件*无关紧要。 他们会互相影响……

好的做法是拥有1个FP到1个文件…如果你需要另一个文件关闭前一个文件

由于打开的文件被视为进程的资源。 因此,这与流程资源和地点更相关

其他答案在技术上解释得更清楚,所以我会保持简单。

首先要了解以下内容

  • fp就像一个头指针。 它在每次读取写操作时向前移动,以便下一次读取或写入文件将从上一操作结束开始。
  • 由于它是一个指针,因此每当它被改变时(在函数中或在主函数中),变化将在任何地方反映出来。
  • 倒带将fp设置为文件的开头

因此,在此示例中,当您使用getdata写入文件时,fp(或头部)在写入每个字符后向前移动,即始终保留在文件的末尾。 然后倒回以将其带回文件的头部。 因此,当您再次打印时,读取从文件的开头开始,而不是从文件的结尾开始。

现在,如果你不倒带,那么fp将保留在文件的末尾,printdata将不会打印任何东西。