warning: passing argument 2 of ‘fopen’ makes pointer from integer without a cast

烂漫一生 提交于 2019-12-25 05:36:18

问题


I have this function to check if a file exists:

#include <stdio.h>

int main(int argc, char **argv) {
    int textFileExists(const char *filename){
        FILE *fp=   fopen(filename,'r');
        if(fp==NULL){
            printf("%s %s.\n","There was an error opening ", filename);
            return -1;
        }
        return 1;
    }

    textFileExists("text.txt");
    return 0;
}

But when I compile this code, I get this warning.

warning: passing argument 2 of ‘fopen’ makes pointer from integer without a cast
  FILE *fp= fopen(filename,'r');

Running this code gives me a segmentation fault.

What is going on here?


回答1:


The usage of literal 'r' as fopen parameter is equivalent to using the following:

const char* filename = ...;
char mode = 'r';
fopen(filename, mode);

The 'r' is therefore assumed to be of type char and has the value of 0x72 (ASCII). This is then passed to the char* mode, converting the 0x72 to a memory address (pointer) to be read from to obtain the characters of mode string by fopen. Accessing the memory location at 0x72 fails as that location is most probably not available to your application.

For a char* literal, you need to use "r" as in

const char* filename = ...;
const char* mode = "r";
fopen(filename, mode);



回答2:


'r' is a single character which, when passed to a function, has type int.

The function fopen() expects the second argument to be a (const) pointer to char (i.e. a const char *). Hence the warning message. A conversion from an int to a pointer is permitted in C, for various reasons, but compilers often treat such conversions as suspicious, and warn you.

The function expects the passed pointer to be a string, which means it assumes the value points to the first character of an array of char. It doesn't (since you have passed an int) so exhibits undefined behaviour. One symptom of undefined behaviour is a segmentation violation (caused by your operating system detecting your program accessing memory it shouldn't, and sending a SIGSEGV signal to your program).

To fix the problem pass "r" instead of 'r'. Note the double quotes rather than single quotes. "r" is a string literal, which is represented using two characters, 'r' and '\0', which is what fopen() expects. Doing this will eliminate both the warning and the error when running the program.

Get in the habit of checking warning messages from your compiler BEFORE running the program. Warnings often indicate a potential problem - in this case, the cause of the warning is also the cause of the abnormal program exit.




回答3:


In C there's a difference between 'r' and "r". Check your C book.



来源:https://stackoverflow.com/questions/41407318/warning-passing-argument-2-of-fopen-makes-pointer-from-integer-without-a-cast

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!