所以我有这段代码
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);
,则行为很奇怪。为什么我需要倒回指针?虽然指向同一个文件并不是fp1
和fp
函数的本地,因此不应该像第一个程序那样相互影响?
答案 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; }
现在当你调用这些函数时,很明显他们会修改底层对象。完成写入文件后,光标指向最后一个元素,如果不fgetc
,rewind
将立即返回EOF。
为了澄清,当您致电fopen
时,您会创建一个存储在某处的FILE
个对象。您无法控制此对象,只需获取指向它的指针即可。如果更容易理解,您可以将此指针(在您的示例中为fp1
)视为文件ID。任何更改都在FILE对象上完成,而不是指针/ ID本身。
答案 1 :(得分:0)
任何打开文件的进程都有一个数据结构,用于存储与文件相关的搜索位置等。无论你打开同一个文件多少次,它都是指向同一个DS的指针。打印两个文件指针的值应该是相同的...所以你访问文件的文件*无关紧要。他们会互相影响......
不错的做法是拥有1个FP到1个文件...如果你需要另一个文件关闭前一个
由于打开的文件被视为进程的资源。因此,这与流程资源和地点更相关
答案 2 :(得分:0)
其他答案在技术上解释得更清楚,所以我会保持简单。
首先要了解以下内容
因此,在此示例中,当您使用getdata写入文件时,fp(或头部)在写入每个字符后向前移动,即始终保留在文件的末尾。然后倒回以将其带回文件的头部。因此,当您再次打印时,读取从文件的开头开始,而不是从文件的末尾开始。
现在,如果你不倒带,那么fp将保留在文件的末尾,printdata将不会打印任何东西。