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

时间:2015-05-13 11:19:49

标签: c file pointers

所以我有这段代码

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函数的本地,因此不应该像第一个程序那样相互影响?

3 个答案:

答案 0 :(得分:2)

让我们看看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; }

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

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

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:0)

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

首先要了解以下内容

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

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

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