警告:传递“fopen”的参数 2 使指针来自整数而不进行强制转换

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

我有这个功能来检查文件是否存在:

#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;
}

但是当我编译这段代码时,我得到了这个警告。

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

运行 这段代码给我一个分段错误。

这是怎么回事?

在 C 中,'r'"r" 是有区别的。检查你的 C 书。

将文字 'r' 作为 fopen 参数的用法等同于使用以下内容:

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

因此,'r' 被假定为 char 类型并且值为 0x72 (ASCII)。然后将其传递给char* mode,将0x72 转换为要读取的内存地址(指针),以通过fopen 获取mode 字符串的字符。访问 0x72 处的内存位置失败,因为该位置很可能对您的应用程序不可用。

对于 char* 文字,您需要使用 "r",如

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

'r' 是单个字符,当传递给函数时,其类型为 int.

函数 fopen() 期望第二个参数是指向 char 的 (const) 指针(即 const char *)。因此警告信息。由于各种原因,从 int 到指针的转换在 C 中是允许的,但编译器通常将此类转换视为可疑,并警告您。

该函数期望传递的指针是一个字符串,这意味着它假定值指向 char 数组的第一个字符。它没有(因为你已经通过了 int)所以表现出未定义的行为。未定义行为的一个症状是分段违规(由您的操作系统检测到您的程序访问了它不应该访问的内存,并向您的程序发送 SIGSEGV 信号引起)。

要解决问题,请传递 "r" 而不是 'r'。注意双引号而不是单引号。 "r" 是一个字符串文字,使用两个字符 'r''[=22=]' 表示,这是 fopen() 所期望的。这样做将消除 运行 程序时的警告和错误。

养成在 运行 程序之前检查编译器警告消息的习惯。警告往往预示着潜在的问题——在这种情况下,警告的原因也是程序异常退出的原因。