简体   繁体   中英

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

I noticed that I had used a char* variable instead of a FILE* variable in my code when using fopen and fgets, but my code works. I am wondering why this is? A 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)) {
...

Both a char* and a FILE* simply store a memory address. C has fairly weak typing (Edit: this was a misunderstanding on my part, see comments below) so it lets you assign pointers without worrying about the type they point to.

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

Your compiler is very permissive. It should have complained that the FILE* to char* conversion is invalid.

Anyway, assuming the compiler accepts this implicit conversion, the answer is quite simple. By the C standard, a char* and a void* pointer can hold, without loss, any pointer value. So, you can convert from SOMETYPE* to char* and then, back from char* to SOMETYPE*, and you get the same pointer you initially had. Actually, on most systems, all pointers are equivalent and you can freely convert from one to another.

FILE* is a small and opaque value of pointer type. Probably an actual pointer to an internal data structure, but this may be implemented differently (eg it might be a UNIX file descriptor converted to a pointer). The STDIO functions just expect that you use the same opaque FILE* value you got from fopen, in fread/fwrite/fclose.

The FILE* is converted to char* when assigned to filePath. The char* is converted to FILE* as the first parameter of fgets (again, your compiler should complain), and so, gets back to its initial value.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM