Fopen / fgets using char * instead of FILE *, why does this work?

I noticed that I used the char* variable instead of the FILE* variable in my code when using fopen and fgets, but my code works. I wonder why this is? The section of my code is as follows.

 ... char* filePath = ac->filepath; char* line = malloc(sizeof(char) * MAX_CHAR_PER_LINE) ; filePath = fopen(filePath, "r"); // we are assigning the result to a char*, not FILE* if (filePath == NULL) { printf ("\n[%s:%d] - error opening file '%s'", __FILE__, __LINE__, filePath); printf ("\n\n"); exit (1); } while ((fgets(line, MAX_CHAR_PER_LINE, filePath) != NULL)) { ... 
+4
source share
2 answers

Both a char* and a FILE* simply store the memory address. C has a pretty weak typing (Edit: it was a misunderstanding on my part, see Comments below), so it allows you to assign pointers without worrying about what type they are pointing to.

fopen returns the address of the FILE object, and you store this address somewhere (in your case, it is in char* ). When you use the address in fgets , it still has the address of the FILE object, so everything will work as expected.

+3
source

Your compiler is very permissive. He should have complained that converting FILE * to char * is invalid.

In any case, assuming the compiler accepts this implicit conversion, the answer is pretty simple. According to the C standard, the char * and void * pointer can hold any value of the pointer without loss. That way you can convert from SOMETYPE * to char * and then back from char * to SOMETYPE *, and you will get the same pointer that you originally had. In fact, on most systems, all pointers are equivalent, and you can freely convert from one to another.

FILE * is a small and opaque pointer type value. The actual pointer to the internal data structure is likely, but it can be implemented in different ways (for example, it can be a UNIX file descriptor converted to a pointer). The STDIO functions simply expect you to use the same opaque FILE * value that you received from fopen in fread / fwrite / fclose.

FILE * converts to char * when assigning filePath. char * converts to FILE * as the first parameter to fgets (again, your compiler must complain), and therefore returns to its original value.

Suggestion: Use a higher level of errors / warnings in your compiler and fix your code.

+1
source

Source: https://habr.com/ru/post/1496220/


All Articles