2015-10-15 101 views
-2

好的,這裏是交易......我記得上週創建一個程序需要我以二進制模式打開文件並將數據寫入它。起初,我嘗試使用fopen函數,檢查結果是否正確,然後嘗試寫入數據。我記得第一次嘗試時,fwrite操作不起作用。然後,在將變量的聲明從一個地方移動到另一個地方之後,我終於能夠使fwrite將數據插入到文件中。現在,我需要創建另一個類似的程序來做一些其他的事情,所以我想使用相同的分配代碼(實際上,我想創建一個特定的功能來做同樣的事情),這裏是我是什麼能夠拿出:C fopen/fwrite驅使我瘋狂 - fwrite不寫作

#include <stdio.h>           

int openfile(FILE *main, char *name, int option);  

int main(void)            
{               

    FILE *main;           
    int header_init;           
    int result;            

    switch (openfile(main,"main_file.bin",1)) { 
    case 1:            
     header_init = -1;         
     //fseek(main,0,SEEK_SET); --> useless 
     fwrite(&header_init,sizeof(int),1,main);  
     printf("ftell = %d\n",ftell(main)); break;  
    case 2:            
     fread(&header_init,sizeof(int),1,main);   
     printf("%d\n",header_init); break;     
    default:            
     printf("Error trying to open file\n");     
    }              
    printf("header_init is %d\n",header_init);    
    fclose(main); exit(0);        
}               

int openfile(FILE *main, char *name, int option)  
{               
    int result_alloc;          
    int F_OK;            
    if (result_alloc = access (name, F_OK) != 0) {   
    printf("File not found, allocating a new one\n");  
    if ((main= fopen(name,"w+b")) != NULL) return 1; 
    }              
    else {             
    printf("File exist, allocating as r+b\n");  
    if ((main= fopen(name,"r+b")) != NULL) return 2; 
    }           
    printf("Failure trying to open"); 
    return 0;         
}            

由於一些不幸的原因,fwrite操作不寫-1到分配的文件。我對這個程序的意圖是,它會一直檢查該特定文件是否存在:如果有一個文件存在,只需用r + b打開它以允許更新功能而不覆蓋實際的文件內容。否則,分配一個頭值爲-1的新文件(我將把這個文件用作帶鏈接列表結構的記錄文件)。

說真的,我不明白爲什麼這不起作用。這個想法和我以前的計劃一樣。唯一改變的是我創建了一個函數,因爲這會在稍後發生(因爲第三個參數可以讓我減少我的代碼並使它更「易讀」 - 至少這是意圖!) 。我必須承認我對細節問題有一些關注,但我正在努力改進它,我可能在這段代碼中錯過了一些愚蠢的東西,但是在幾個小時看着它之後,我真的很想在這裏尋求一些幫助。謝謝

編輯:我在z/Linux下運行它。我想了解的是,爲什麼上面的代碼不向文件寫入-1,但下面的代碼可以正常寫入?

#include <stdio.h>             
int main(void)              
{                 
    FILE *main;              
    int result_alloc;             
    int header_init;             
    int F_OK;               

    if (result_alloc = access ("test.bin", F_OK) != 0) {    
    printf("File not found, allocating a new one\n");    
    if ((main = fopen("test.bin","w+b")) == NULL) {     
     printf("Failure trying to open file");      
     return 1;              
    }                
    else {               
     header_init = -1;            
     printf("current pos is: w+b %d\n",ftell(main));    
     fwrite(&header_init,sizeof(int),1,main);      
     printf("current pos is: write header_init %d\n",ftell(main)); 
    }                
    }                 
    else {               
    if ((main = fopen("test.bin","r+b")) == NULL) {     
     printf("Failure trying to open file");      
     return 2;              
    }                
    else {               
     printf("current pos is: r+b %d\n",ftell(main));    
     fread(&header_init,sizeof(int),1,main);      
     printf("current pos is: read header_init %d\n",ftell(main)); 
    }                
    }                 
}                 
+8

C是傳遞值。更改被調用者中的函數參數不會更改調用者中的相應參數。此外,你*真的*需要回到基礎:'int F_OK;/**/access(name,F_OK);'不會做你認爲它的作用。 *做*啓用編譯器警告。 – EOF

+2

@EOF是正確的:函數'openfile()'的正確原型是'openfile(FILE ** main,char * name,int option)'。它必須由'openfile調用(&main,「main_file.bin」,1)' – francis

+2

您想要了解如何使用調試器,逐步跟蹤代碼並檢查所有相關變量的值。通過這種方式,您可以詳細觀察發生了什麼,並且無需再在黑暗中進行挖掘。 – alk

回答

1

的主要問題,即轉讓給main變量openfile函數內沒有被調用函數可見。因爲C是按值傳遞的,所以只改變函數參數的值,而不是傳入的變量的值。因此,當openfile返回時,main函數內部的main變量不變。

你需要做的是將該變量的地址傳遞給該函數,然後在該函數內解引用局部變量(這是一個指針),併爲解除引用的變量賦值。

另外,因爲它隱藏了該範圍內的功能並且可能導致混淆,所以將某個變量與某個函數的名稱相同並不是一個好主意。

int openfile(FILE **fp, char *name, int option); 

你可以這樣稱呼它(改變main變量的名稱fp):

FILE *fp; 
... 
openfile(&fp,"main_file.bin",1) 

隨後的openfile

所以,你會如下定義功能,請取消fp以更改呼叫功能中的值:

*fp = fopen(name,"w+b") 

第二個代碼示例工作的原因是,您直接分配給局部變量,然後在函數中稍後使用該變量。

而且,你是「幸運」的是代碼的第二件工作,因爲你這樣做:

int F_OK; 

F_OK在unistd.h中,其中access()定義已定義。所以通過這樣做,你可以重新聲明它,而不是給它一個價值,導致未定義的行爲。擺脫這個定義,#include <unistd.h>,並呼籲access()保證按預期工作。

+0

釘住它!現在我懂了。如果這是一個初學者問題,我很抱歉,但我真的想聽到某人的消息。這最後的迴應剛剛解決了我的問題,並教會了我幾件事。當然其他評論也很好,我知道我對C不太好,但希望我能成爲專家(某天!)。現在它工作正常!我想通過定義一個函數來適應這種類型的事情,我之前的代碼需要很多函數來幫助提高可讀性,而這些答案明確地幫助了我。謝謝大家! – Rodrigo