2012-05-14 16 views
0

私は何か困ったことを理解する助けをすることができます。これは、ファイルを読み出すためのfopen()の位置に関係します。コード(GCC 4.5.2でコンパイルされたC)後なぜfopenが使用されるかは重要ですか?

int main (int argc, char** argv) { 
    FILE * pFile; 
    try_fopen(pFile, argv[1], "r"); // Gives a Segfault 

    printf ("The file contains %d ones.\n", cnt_ones(pFile)); 
    fclose (pFile); 

    return 0; 
} 

主にそれを入れている間:

#include <stdlib.h> 
#include <stdio.h> 

void try_fopen(FILE* f_handle, const char* f_name, const char* mode) { 
    f_handle = fopen(f_name, mode); 
    if(f_handle == NULL) { 
     fprintf(stderr, "Error: Unable to open '%s'.", f_name); 
     exit(EXIT_FAILURE); 
    } 
} 

int cnt_ones(FILE* pFile) { 
    int c; 
    int n = 0; 

    do { 
     c = fgetc (pFile); 
     if (c == '1') n++; 
    } while (c != EOF); 

    return n; 
} 

なぜ、それが機能にはfopenを置くこととSegfaultを与えることです(もしそうでない場合):

int main (int argc, char** argv) { 
    FILE * pFile; 
    pFile = fopen(argv[1], "r"); // While this doesn't give a Segfault 
    if(pFile == NULL) { 
     fprintf(stderr, "Error: Unable to open '%s'.", argv[1]); 
     exit(EXIT_FAILURE); 
    } 

    printf ("The file contains %d sign characters.\n", cnt_ones(pFile)); 
    fclose (pFile); 

    return 0; 
} 
+1

?ポインタを返すか、ダブルポインタを使用します。 – janneb

+0

私は今、私の方法の誤りを見る。 –

答えて

4

Cは値渡しであり、参照渡しではありませんので、poiを渡す必要がありますpFileにNTER、そうでなければ、関数スコープの外でそれを変更しないでください:

void try_fopen(FILE** f_handle, const char* f_name, const char* mode) { 
    *f_handle = fopen(f_name, mode); 
    if(*f_handle == NULL) { 
     fprintf(stderr, "Error: Unable to open '%s'.", f_name); 
     exit(EXIT_FAILURE); 
    } 
} 

// ... 
try_fopen(&pFile, argv[1], "r"); 
1

ポインタpFileが機能try_openに値によって渡されるため。関数内で変更された値は、mainでは使用できません。これを解決するには、関数へのポインタのアドレスを渡す必要があります。したがって、try_openFILE**を受け入れ、fopenの結果を*pFileに割り当てます。この関数を呼び出す際には&pFileを使用してpFileのアドレスを渡す必要があります。

0

理由は簡単です。機能*にFILE *を渡すと、値が渡されると更新が失われます。 FILE **を関数に渡してみてください。そうすれば動作します。

コードスニペットのために上記Binyamin Sharetの回答を参照してください。この理由は、あなたが戻り値として* FILEを返すようにtry_open機能を変更することができ、このlink

それとも

を読むことによって理解することができます。

FILE *try_fopen(const char* f_name, const char* mode) 
{ 
    FILE *f_handle = NULL;  
    *f_handle = fopen(f_name, mode);  
    if(*f_handle == NULL) 
    {   
    fprintf(stderr, "Error: Unable to open '%s'.", f_name);   
    exit(0);  
    } 
} 

    //In the main function. 
    FILE *pFile = try_fopen(argv[1], "r"); 
1

あなたはどちらかを行うことができます。

File * fp; 
try_fopen(&fp,.....); /* void try_fopen (FILE ** fp,....) */ 

または以下:ファイル*ポインタが値によって渡されるため

File * fp = try_fopen("file name"); /* FILE * try_fopen (const char * file_name,...) */ 
関連する問題