警告:传递“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()
所期望的。这样做将消除 运行 程序时的警告和错误。
养成在 运行 程序之前检查编译器警告消息的习惯。警告往往预示着潜在的问题——在这种情况下,警告的原因也是程序异常退出的原因。
我有这个功能来检查文件是否存在:
#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()
所期望的。这样做将消除 运行 程序时的警告和错误。
养成在 运行 程序之前检查编译器警告消息的习惯。警告往往预示着潜在的问题——在这种情况下,警告的原因也是程序异常退出的原因。