0

I am able to write the following main program:

int main(){
#include <stdio.h>
#include <stdlib.h>

FILE *fpointer = fopen("file.txt", "r+");

if (fpointer == NULL){
    printf("file does not exist!\n");
    return EXIT_FAILURE;

fclose(fpointer);
return 0;
}

However, I am not able to split this into a new function (open file and check for existince). I want to call the new function checkFileExistence(). This is how I tried to write it:

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

int checkFileExistence(char* filepath){

        FILE* file=fopen(filepath,"w");

        if (file == NULL){
                printf("File does not exist!");
                return EXIT_FAILURE;
        }

        return EXIT_SUCCESS;
}

int main(){

        char* filepath = "test.txt";
        FILE* new_file_pointer=checkFileExistence(filepath);

        fclose(new_file_pointer);

        return 0;
}

But I keep getting errors for hours now. The error at this point is:

file.c:19:8: warning: incompatible integer to pointer conversion initializing 'FILE *'
      (aka 'struct __sFILE *') with an expression of type 'int' [-Wint-conversion]
        FILE* new_file_pointer=checkFileExistence(filepath);

How do I code correctly? I just want to use an own function to check the existence of a file without putting everything into the main function. Thank you in advance for the answer. I looked into the theory of data types, but still aren't able to use this correctly, because the pointer are somehow confusing me. Thank you very much. I love this platform and always appreciate all answers!

kingkonzgg
  • 23
  • 4
  • Why did you change the mode argument from `"r+"` in your first (successful) code to `"w"` in your second attempt? That would make a difference, for sure. – Adrian Mole Mar 08 '21 at 17:40
  • Also, this may be useful: https://stackoverflow.com/q/13508712/10871073 – Adrian Mole Mar 08 '21 at 17:43
  • Hello, thank you for your answer. I am pretty new to this topic and I just want to check the existence of a file. I want to check it regardless of the mode (sometimes I need to open it, sometimes I need to write to a file). If I change the mode, I keep getting the same error, did I do something wrong ? – kingkonzgg Mar 08 '21 at 17:44
  • You seem to be missing `int main(void) {` or thereabouts in the first fragment that you claim is a `main` program. – Jonathan Leffler Mar 08 '21 at 17:47
  • 1
    You need to double check your return types and what you expect to be returned from your function call to `checkFileExistence`. – Trey Keown Mar 08 '21 at 17:47
  • Thank you, changing main into main(void) does not do anything (?) :) – kingkonzgg Mar 08 '21 at 17:50
  • Thank you @TreyKeown, how do I do it properly in this case? Trying to change the return type for hours now, keep getting errors – kingkonzgg Mar 08 '21 at 17:51
  • Thank you @AdrianMole, I looked into the answer from your URL. I want to use my own function instead of using it from another library :) just wanna split it into different parts, because this is how I learn how to code functions properly – kingkonzgg Mar 08 '21 at 17:56
  • I am new to functions in general and want to do it my own way, so I can learn how I do it the next time. This is the reason why I don't wanna use pre-build functions from any libraries – kingkonzgg Mar 08 '21 at 18:00
  • 1
    By the way, `EXIT_SUCCESS` and `EXIT_FAILURE` are meant to be used for exit codes, not normal function returns. In fact, you'd probably want 1 for true and 0 for false, yet `EXIT_SUCCESS` is defined as 0 and `EXIT_FAILURE` is defined as 1. – mediocrevegetable1 Mar 08 '21 at 18:05
  • Oh, thank you very much @mediocrevegetable1. I did not know! – kingkonzgg Mar 08 '21 at 18:15

2 Answers2

1

Your return type from checkFileExistence() is int. But in main(), you are assinging it to a variable of datatype FILE.

Try changing

FILE* new_file_pointer=checkFileExistence(filepath);

to

int existance_status = checkFileExistence(filepath);

but this would cause a variable scope error, you might want to look out for that too!

Criss Hills
  • 189
  • 1
  • 12
  • Hello, wow this looks like really clean code. Thank you, it looks like you found the cause of my issue. Is it possible to change more of my code fragments so that I don't get any errors? Thank you in advance – kingkonzgg Mar 08 '21 at 17:46
  • If I change existance_status to ```int``` type, I can't close the file, do I ? Just want a simple solution to get a working function, which checks for the existence of a file – kingkonzgg Mar 08 '21 at 17:47
  • 1
    @kingkonzgg is there any reason why you don't want to close the file inside `checkFileExistance` too? – mediocrevegetable1 Mar 08 '21 at 18:06
  • No, not really. I just don't want to open the file twice, if possible @mediocrevegetable1. And I don't know the correct synthax for using it (even if it's basic for you guys) – kingkonzgg Mar 08 '21 at 18:14
  • I want to open the file inside the function ```checkFileExistence```, but I want to proceed with the contents of the file inside the main block, if that makes sense. Do I need to open it twice then ? – kingkonzgg Mar 08 '21 at 18:17
  • The main function should do something with the file itself later on, the function ```checkFileExistence``` should just check if it exists or not in first place – kingkonzgg Mar 08 '21 at 18:18
  • functions aren't really necessary for implementations so small. Moreover, if a certain file doesn't exist, the convention is to do `exit(1)` rather than continue with the program unless you have programmed that case too – Criss Hills Mar 08 '21 at 18:21
  • 1
    @kingkonzgg I see. Personally, I would just do all of this outside any function unless I'm opening a lot of files at once. But if you really do want to keep it in a function and don't want to use any other functions (if you don't mind, [this](https://stackoverflow.com/questions/230062/whats-the-best-way-to-check-if-a-file-exists-in-c) post may have some nice suggestions), I'd honestly just suggest you open it twice. It doesn't seem like your program would really suffer too much. – mediocrevegetable1 Mar 08 '21 at 18:22
  • Thank you @CrissHills. In this case, I want to use a small function because I am still new to programming and I want to learn how to split them. You are right, exit(1) would be better. Is it possible to change the type of ```checkFileExistence``` to something I can give a parameter into? My issue is I don't know how to use parameters for functions, thank you – kingkonzgg Mar 08 '21 at 18:24
  • Thank you @mediocrevegetable1. You are really helping me out. Could you, if you don't mind, code that quickly and put it into an (own) answer? I would like to appreciate your efforts for helping me out that much ! I am still confused how I use the correct data types, even if I open it twice.Thank you – kingkonzgg Mar 08 '21 at 18:26
  • 1
    @kingkonzgg Are you talking about this _"Personally, I would just do all of this outside any function unless I'm opening a lot of files at once"_? If so, nothing much for me to code, really. I'm simply saying to do everything in your function directly in the main function, so open the file outside the function and do the `if` statement outside too (to check if it doesn't exist). If it doesn't exist, do something to handle the issue or exit. If it exists, all's good and you can continue onward. This way, it wouldn't possibly have to open twice. – mediocrevegetable1 Mar 08 '21 at 18:30
1

Hmmmm.... if you #include <stdio.h> inside the body of main you'll probably run into trouble, as that limits the scope of all definitions made in stdio.h to the body of main. So you'll have to include it again if you need the stdio.h definitions in a different function you write after main. But this will not work, as stdio.h defines a flag that avoids it to be included again in the same compilation unit, to prevent double definition errors. So, never #include <stdio.h> inside a function or a block delimited by { and }.

Anyway, you have several problems in your second snippet of code:

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

int checkFileExistence(char* filepath){

if you return int, you cannot assign it to a FILE * variable, as you have in your main routine. Better use FILE * checkFileExistence(char* filepath) as your prototype for the function.


        FILE* file=fopen(filepath,"w");

        if (file == NULL){
                printf("File does not exist!");
                return EXIT_FAILURE;

EXIT_FAILURE is an integer, but you want to return a pointer. It should be better to just exit(EXIT_FAILURE); so the program is finished (if you cannot open the file, what else you can do?) or return NULL, to indicate some trouble in the opening of the file to the calling code.

        }

        return EXIT_SUCCESS;

You should return the FILE * obtained from fopen, or you will have nothing to operate upon in main. Better write return file;.

}

int main(){

        char* filepath = "test.txt";
        FILE* new_file_pointer=checkFileExistence(filepath);

        fclose(new_file_pointer);

        return 0;
}

So your file, after editing, should be something like:

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

FILE *checkFileExistence(char* filepath){

        FILE* file=fopen(filepath,"w");

        if (file == NULL){
                printf("File does not exist!");
                exit(EXIT_FAILURE);
                /* or return NULL; */
        }

        return file;
}

int main(){

        char* filepath = "test.txt";
        FILE* new_file_pointer=checkFileExistence(filepath);

        /* it should be convenient you say something, as you'll get the file
         * opened and closed without you seeing anything at the terminal. */
        if (new_file_pointer != NULL) {
            printf("File opened successfully\n");
        }

        fclose(new_file_pointer);

        return 0;
}
Luis Colorado
  • 10,974
  • 1
  • 16
  • 31
  • Since `#include` is a preprocessor directive, wouldn't there not really be any scope to it (though yes you wouldn't be able to use stuff in the header from before you `#include`ed)? Furthermore, IMHO returning a FILE * just seems weird, since checking for the NULL would probably just be as long as checking from `fopen` directly. Even if you exit instead of returning NULL, it seems like it could be done with a simple `if` statement outside any function again. Honestly, the more I look at OP's program and the function, the better it seems to just not use any function at all. – mediocrevegetable1 Mar 09 '21 at 09:00
  • Actually, nevermind the `#include` thing, I just tested and putting a function declaration in another actually works. Hadn't known about that :P – mediocrevegetable1 Mar 09 '21 at 09:08
  • Thank you, this solved lots of my questions ! – kingkonzgg Mar 10 '21 at 20:08