2016-11-23 4 views
0
#include<stdio.h> 

void hello(FILE * fp) 
{ 
    if((fp = fopen("log","r")) == NULL) 
     printf("%s", "Error opening file"); 
} 

void main() 
{ 
    char p; 
    FILE *sf=fopen("prac.txt","r"); 
    hello(sf); 

    p=fgetc(sf); 
    printf("%c",p); 
} 

私はhello機能を経由してlogをファイルを指すファイルポインタsfを変更するようだったが、printfはまだprac.txtファイルの内容を印刷しています。他の機能を経由してファイルポインタを更新

+0

あなたは、このような – macroland

+0

あなたのコードfilename' '文字列としてご' hello'の二番目の引数を、必要とするが、純粋なCで、私はC++のタグを削除しました。 CとC++は**同じ言語ではありません** – wasthishelpful

+4

[C言語の関数に渡されたポインタを変更するにはどうすればいいですか?](http://stackoverflow.com/questions/766893/how-do -i-modify-a-pointer-a-of-a-function-in-c) –

答えて

0

あなたは(あなたが関数を呼び出すとき、ポインタの値がコピーされ、それがで破壊されていますfpのみ機能helloの範囲内に存在し、void hello(FILE *fp)

#include<stdio.h> 
void hello(FILE ** fp) 
{ 
fclose(*fp); 
if((*fp = fopen("log","r")) == NULL) 
    printf("%s", "Error opening file");  
} 

void main() 
{ 
char p; 
FILE *sf=fopen("prac.txt","r"); 
hello(&sf); 

p=fgetc(sf); 
printf("%c",p); 
} 
+0

http://stackoverflow.com/questions/8441059/what-happens-to-file-pointer-ファイル終了時 fpがfcloseの後でnullの場合fpは新しいfpを返します – Aymanadou

+0

Erm、いいえ、fcloseは '* fp'を変更しないので、単にNULLになっていますか? – Vatine

2

それをreopning前にファイルを閉じる必要がありますfuncの終わり)。

これは動作します:

#include<stdio.h> 

FILE* hello(FILE * fp) 
{ 
    fclose(fp); 
    if((fp = fopen("log","r")) == NULL) { 
     printf("%s", "Error opening file"); 
     return NULL; 
    } 
    return fp; 
} 

void main() 
{ 
    char p; 
    FILE *sf=fopen("prac.txt","r"); 
    sf = hello(sf); 

    if (sf != NULL) 
    { 
     p=fgetc(sf); 
     printf("%c",p); 
    } 
} 
+0

@Vatine solution作品も – Fefux

+0

ありがとうございます.....私はなぜこのfclose(fp)が必要なのですか?............私は 'sf'ポインタアドレスを参照によって呼び出して更新しようとしていました – enamel

+0

答えを読むAdam Rosenfieldのfcloseについて:http://stackoverflow.com/questions/8175827/what-happens-if-i-dont-call-fclose-in-ac-program。別のポイントは、ここであなたはsfポインタアドレスをpdateすると、sfポインタのコピーを直接更新します。参照で呼び出すときは、変数のアドレスを送信する必要があります。あなたの変数がポインタの場合は、ポインタのポインタを送る必要があります。ここでsfは 'FILE *'であり、アドレスタイプは 'FILE **'です(Vatineの解答を参照) – Fefux

3

あなたは、あなたがFILE**を渡す必要があるために何FILE*ポイント変更したい場合。あなたがそれを変更する前に、それが起こっているファイルが閉じられていることを確認する必要があります。これは、FILE*の変数をfcloseの後で常にNULLに設定することにも依存します(自動的には発生しません)。この関数を不用意に使用すると、FILE*fcloseが呼び出されます。しかしこれはおそらく、意図的にファイルディスクリプタを漏らし、ファイルをフラッシュしないことよりも優れています。

void hello(FILE **fp) 
{ 
    // This is actually a horrible test. And in general, this is not 
    // something you should do, but it is better than leaking open 
    // file descriptors, so, yeah, 
    if (*fp != NULL) { 
    fclose(*fp); 
    *fp = NULL; 
    printf("Closed file."); 
    } 
    if((*fp = fopen("log","r") == NULL) { 
    printf("%s", "Error opening file"); 
    } 
} 
+0

なぜ閉じる必要がありますか? – enamel

+0

@enamelいくつかの理由。 「書き込まれた」データ(ただし、プログラムによってまだバッファされている)は失われる可能性があります。 「オープンファイル」は非常に限られたリソースなので、それらを浪費しないでください。そのようなFILE *を上書きすると、後でそれを閉じたり、フラッシュしたりすることができません。 – Vatine

0

これは、引数をコピーするためです。ファイルポインタの内容は、アドレスのローカルコピーのみを上書きしません。

ファイルポインタ自体は更新されません。これをアーカイブするには、関数へのポインタへのポインタを渡し、それに応じて参照解除するか、新しいファイルポインタを返し、古いポインタを上書きします。とにかくファイルを閉じるのを気にします。

0
#include<stdio.h> 
// Use double pointer since fp is getting address of a pointer variable 
void hello(FILE ** fp) 
{ 
    // If the file is already pointing to some file then close that file 
    if(*fp != NULL) 
    { 
     fclose(*fp); 
     *fp = NULL; 
    } 
    if((*fp = fopen("log","r")) == NULL) 
     printf("%s", "Error opening file"); 
} 

int main() 
{ 
    char p; 
    FILE *sf=fopen("prac.txt","r"); 
    // While sending the file pointer you need to send the address of the file pointer 
    hello(&sf); 

    p=fgetc(sf); 
    printf("%c",p); 

    return 0; 
} 
関連する問題