1
#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);
}

I wanted to change the file pointer sf to point to file log via hello function but printf is still printing the content of prac.txt file.

rocambille
  • 15,398
  • 12
  • 50
  • 68
enamel
  • 81
  • 6
  • you need a second argument to your `hello`, such as `string filename` – macroland Nov 23 '16 at 08:44
  • Your code is pure C, I removed the C++ tag. C and C++ are **not** the same language – rocambille Nov 23 '16 at 08:49
  • 4
    Possible duplicate of [How do I modify a pointer that has been passed into a function in C?](http://stackoverflow.com/questions/766893/how-do-i-modify-a-pointer-that-has-been-passed-into-a-function-in-c) – Ruslan Osmanov Nov 23 '16 at 08:54

5 Answers5

3

If you want to change what the FILE* points to, you need to pass a FILE**. Before you change it, you need to ensure that any file it happens to be pointing to is closed. This also relies on you always setting FILE* variables to NULL after fclose (this, alas, does not happen automatically), so there's a decent chance careless use of this function would call fclose on an already-closed FILE*. But this is probably still better than willfully leaking file descriptors and not flushing files.

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");
  }
}
Vatine
  • 20,782
  • 4
  • 54
  • 70
  • why closing is required? – enamel Nov 23 '16 at 09:04
  • @enamel Couple of reasons. Data that has been "written" (but is still buffered by the program) may get lost. "Open files" is a very limited resource, so you should not waste them. And if you over-write a FILE* like that, you have absolutely no way of being able to close it, or flush it, afterwards. – Vatine Nov 23 '16 at 09:42
2

In void hello(FILE *fp), fp only exists in the scope of the function hello (the value of the pointer is copied when you call the function and it's destroyed at the end of the func).

This works:

#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);
    }
}
rocambille
  • 15,398
  • 12
  • 50
  • 68
Fefux
  • 964
  • 5
  • 12
  • thank you ..... why we require this fclose(fp)? ............ i was trying to update the 'sf' pointer address by call by reference – enamel Nov 23 '16 at 09:02
  • Read the answer of Adam Rosenfield for fclose : http://stackoverflow.com/questions/8175827/what-happens-if-i-dont-call-fclose-in-a-c-program. Another point, here you don't update the sf pointer address, you update directly a copy of the sf pointer. When you call by reference, you have to send the address of your variable. If your variable is a pointer, you have to send a pointer of pointer. Here sf is `FILE*` and it address type is `FILE**` (see Vatine's solution) – Fefux Nov 23 '16 at 09:10
0

you should close the file before reopning it

#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);
}
Aymanadou
  • 1,200
  • 1
  • 14
  • 36
  • http://stackoverflow.com/questions/8441059/what-happens-to-file-pointer-after-file-is-closed fp is null after fclose , fopen givs a new fp – Aymanadou Nov 23 '16 at 09:07
  • Erm, no, `fclose` does not change `*fp`, so "is it NULL` is merely a convention. – Vatine Nov 23 '16 at 09:44
0

This is because you copy arguments. You do not override the content of the file pointer only the local copy of the address.

The file pointer itself is not updated. To archive this either pass a pointer to a pointer to the function and dereference accordingly or return the new file pointer and override the old one. Anyways care for closing the file.

Thomas Pinetz
  • 6,948
  • 2
  • 27
  • 46
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;
}
ani627
  • 5,578
  • 8
  • 39
  • 45