2015-05-13 46 views
1

所以我有這樣的代碼傳遞給函數時文件指針的行爲有所不同。爲什麼?

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; 
} 

和輸出是顯而易見的。

​​

但文件指針不以相同的方式工作。我試圖編寫一個將數據附加到文件中的基本代碼。

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,所以不應該像第一個程序中那樣影響對方?

+0

'fputc','putc'和'rewind'改變指針指向的io對象。因此,指針是本地的並不重要。 –

+0

'fputc(ch,fp);'''getdata''應該是'fgetc(ch,fp)',對不對?順便說一句,'ch'應該是'int'類型,而不是'char'。 –

+0

@CoolGuy問題是,我沒有看到_prints_ __all__元素的聲明。 –

回答

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將立即返回EOF,如果您不是rewind


爲了澄清,當你調用fopen您創建的地方存儲在一個FILE對象。你無法控制這個對象,你只需要一個指向它的指針。如果它更容易理解,您可以將此指針(在您的示例中爲fp1)視爲文件ID。任何更改都是在FILE對象上完成的,而不是指針/ ID本身。

+0

明白了。謝謝!! –

0

enter image description here任何打開文件的進程都有一個數據結構,用於存儲與文件有關的查找位置等。無論您打開同一個文件多少次,它都是指向同一個DS的指針。打印這兩個文件指針的值應該是相同的...因此,與訪問該文件的File *無關。它們會影響對方的工作...

好的做法是,1 FP 1文件...如果您需要另一個關閉之前的

當打開的文件數爲資源的過程。因此,這更多地涉及到工藝資源,然後當地

+0

yup +1。謝謝。 –

+0

你確定嗎?我只是試着打開同一文件兩次,從第一個'FILE'指針讀取,然後從第二個讀取。它從一開始就開始了。你有沒有提到你的說法? –

+0

http://stackoverflow.com/a/17353503/3884862 – theadnangondal

0

其他答案解釋它更技術上,所以我會保持簡單。

首先了解以下

  • FP就像一個頭指針。它在每次寫操作讀取時向前移動,以便下一次讀取或寫入文件將從前一操作結束時開始。
  • 由於它是一個指針,因此無論何時它被改變(在一個函數中或在主函數中),這些改變將被反射到任何地方。
  • 倒帶設置FP到文件

所以在這個例子中,當你寫入的文件使用的GetData,FP(或頭)開始寫每個字符後向前移動,即始終保持在文件的結尾。然後倒帶完成,使其回到文件的頭部。因此,當您再次打印時,閱讀將從文件開頭開始,而不是從文件結束開始。

現在,如果不倒帶,那麼fp將保留在文件末尾,printdata將不會打印任何東西。

相關問題