-1

I want to create the function that opens a file and then other functions use this opened file. This is my code,

#include <stdio.h>

int openFile(FILE* inputFile)
{
    inputFile = fopen("input.txt", "r");

    if (inputFile != NULL)
        return 0;
    else
        return -1;
}
void readWholeFile(FILE* inputFile)
{
    char str[20];
    while (feof(inputFile)) {
        fscanf(inputFile, str);
        printf("%s\n", str);
    }
}
int main() {

    FILE* inputFile;

    if (openFile(inputFile) == 0) {
        readWholeFile(inputFile);
    }
    else
        printf("File didn't open");
        fclose(inputFile);    

    return 0;
}

"File didn't open" is not printed so the file should be opened but actually readWholeFile prints nothing as a file would be empty. What's the problem?

Smorts
  • 95
  • 6

2 Answers2

1

Your prototype makes no sense, openFile() can't change the caller's FILE * when it's passed by value, you need to pass the address of the pointer in that case:

int openFile(FILE **inputFile)
{
  *inputFile = fopen("input.txt", "rt");
  return *inputFile == NULL ? -1 : 0;
}

But of course this serves very little purpose, just use fopen() directly where you want to open a file, instead. Returning the pointer to the open file is easier to work with, instead of having to manage a separate int that carries no added value or information (an int being 0 or -1 is not "better" than a pointer being NULL or not NULL).

unwind
  • 391,730
  • 64
  • 469
  • 606
0

You should return inputFile itself. That wauy you can reused it from other function. Also why pass that FILE* to openFile function? It's redundant.

Design-wise you can pass the filename and the parameters like r,w etc.

FILE* openFile(const char*name, const char*params)
{
    inputFile = fopen(name, params);

    if (inputFile != NULL)
        return inputFile;
    else
        return NULL;
}

But in doing that you are just abstracting out the fopen() call. You still have to check the return value of openFile(). You can use double pointer and achieve the same thing but yes I have provided with an alternative.

FILE *inputFile = openFile("input.txt","r");
if( !inputFile ){
    //...
}

The thing is as far as the method shown this is really doing anything other than wrapping the fopen() call. What you can get to know from this answer that you can pass the pointer around in Functions and how to use it.

Other answer provides how you use the double pointer but do you get what happened in previous case?

You are changing the local variable that is passed to openFile(). You change it. And when the function completes then that local variable is not there anymore. It's value wont affect the FILE* variable in main().

To be clear you don't need this method to open a file. It's better if you use the 2 lines alone. Because there is no improvement whatsoever. You still have to check the return value just like you would have in case of direct fopen call.

user2736738
  • 30,591
  • 5
  • 42
  • 56