C 编译错误
我一直在创建一个函数,它应该打开一个文件catalogname[]。然而,每当我编译时,我都会遇到这两个我无法理解的错误 a3.c:在函数“openCatalog”中: a3.c:20:警告:来自不兼容指针类型的赋值C 编译错误,c,compilation,C,Compilation,我一直在创建一个函数,它应该打开一个文件catalogname[]。然而,每当我编译时,我都会遇到这两个我无法理解的错误 a3.c:在函数“openCatalog”中: a3.c:20:警告:来自不兼容指针类型的赋值 catalogname = fopen ("*catalogname", "r"); a3.c:22:警告:return从整数生成指针,但不使用强制转换 这是我的密码: FILE* openCatalog(char catalogname[]) { catalogname
catalogname = fopen ("*catalogname", "r");
a3.c:22:警告:return从整数生成指针,但不使用强制转换
这是我的密码:
FILE* openCatalog(char catalogname[])
{
catalogname = fopen ("*catalogname", "r");
if(fopen != 0)
{
return 1;
}
else
{
return 0;
}
}
提前感谢您提供的任何见解
不兼容的指针类型
catalogname = fopen ("*catalogname", "r");
catalogname是字符char catalogname[]的数组,而fopen返回一个文件指针文件*。当然,将文件指针指定给char数组是一种不同类型的指针,而且,不可指定也没有任何意义
return从整数生成指针,不使用强制转换
您声明函数返回FILE*here:FILE*openCatalog。。。。但是,您的返回语句是return1;然后返回0;。在这里,编译器认为您希望返回值为1或0的文件指针,从而返回响应
事实上,你有很多错误,其中一些错误被兔子掩盖了 第一:
catalogename = fopen("*catalogname", "r");
这是错误的。我想你想要的是:
FILE *fPtr = fopen(catalogname, "r");
然后,在此之后,函数的主体发生了很大的变化:
if (fPtr == NULL || ferror(fPtr) != 0) // if the file isn't NULL or if there is no errors with opening the file...
{
if (fPtr != NULL) // never try to close a NULL file ...
fclose(fPtr);
return NULL; // best way to report an error in C - return NUL or set errno
}
else
{
return fPtr; // return the file we just made.
}
第一个警告是:
您正在将fopen返回的文件*分配给catalogname,即char[]
第二个警告是:
当您返回整数0或1时,函数返回类型FILE*
你还想要别的吗?比如:
FILE* openCatalog(char catalogname[])
{
FILE* file = fopen (catalogname, "r");
对这段代码的完整解释需要一段时间 简介如下:
FILE *openCatalog(char catalogname[])
{
FILE *fp = fopen(catalogname, "r");
return(fp);
}
这将打开命名文件进行读取,并返回文件流指针
另一个简短版本检查文件是否可以打开:
int openCatalog(char catalogname[])
{
FILE *fp = fopen(catalogname, "r");
if (fp != 0)
{
fclose(fp);
return 1;
}
else
{
return 0;
}
}
训诂
原代码为:
FILE* openCatalog(char catalogname[])
{
catalogname = fopen ("*catalogname", "r");
if(fopen != 0)
{
return 1;
}
else
{
return 0;
}
}
我们没有“打开文件”以外的规范。给定函数签名,您似乎希望返回打开文件的FILE*FILE流指针。因此,让我们在此基础上对代码进行评论
功能原型线正常;可以使用char const catalogname[]来强调函数不会修改文件名,但这是一种改进,而不是修复错误的更改
函数中catalogname的类型为char*。在函数的参数列表中,数组大致相当于指针。我通常会编写FILE*openCatalogchar const*catalogname来强调在函数中,它是一个char const*变量。然而,使用您使用的数组表示法是100%合法的;对于我来说,使用指针符号纯粹是一种风格上的偏好
下一个可执行行有几个问题。对fopen的函数调用在技术上并没有错误,尽管它打开的文件是固定名称*catalogname,而不是变量catalogname中指定的文件。要解决这个问题,您需要删除引号。*将给您一个字符而不是字符串,并且它将是文件名的第一个字符。所以,把*也去掉
这样,fopen将返回一个值,实际上是一个文件*,然后将其分配给catalogname,即char*。这是类型不匹配,编译器会对此发出警告。如第一次重写中所示,更正常的处理方法是:
FILE *fp = fopen(catalogname, "r");
这说明了错误消息的原因:
a3.c:20: warning: assignment from incompatible pointer type
我们不知道您的目录是文本文件还是二进制文件。如果它是一个二进制文件,那么如果您在Windows上使用rb打开它,因为它确实很重要,而且在类Unix的系统上也可以使用rb打开它,因为文本文件和二进制文件之间没有区别
代码中的下一行是条件:
if (fopen != 0)
这实际上检查函数fopen的函数指针是否为null。并且C标准保证在您使用的托管环境中,没有函数指针是空的。因此,编译器可以优化该测试,以假设该条件始终为真
您实际需要的是测试结果:
if (fp != 0)
然后有两个return语句,一个返回1,一个返回0。返回1的函数会引发关于将整数转换为指针的警告,因为该函数定义为返回文件*,而1是整数
这说明了您的其他警告消息:
a3.c:22: warning: return makes pointer from integer without a cast
返回0的返回不会生成警告,因为0是一个空指针常量,对于这样的函数来说,这是一个有效的返回值
代码可能只是从fopen返回值。在该函数或调用函数中的某个位置测试该值是正确的,以确保打开成功。您可以在此处使用以下方法进行测试:
if (fp == 0)
err_report_and_exit("Failed to open file %s (%d: %s)\n",
catalogname, errno, strerror(errno));
使用errno和strerror意味着您还应该包括标题:
#include <errno.h>
#include <string.h>
总的来说,这导致:
FILE *openCatalog(char catalogname[])
{
FILE *fp = fopen(catalogname, "r");
if (fp == 0)
err_report_and_exit("Failed to open file %s (%d: %s)\n",
catalogname, errno, strerror(errno));
return(fp);
}
如果函数的目的是检查文件是否可以打开读取,那么上面提到的问题基本相同。我首先展示的修订代码有点冗长。因为假定的目的是检查文件是否
n打开时,调用代码应负责处理“无法打开的情况”;它知道要生成什么样的诊断。这是修订版的一个稍微紧凑的版本,但此版本和上面版本的目标代码是相同的
int openCatalog(char catalogname[])
{
FILE *fp = fopen(catalogname, "r");
if (fp != 0)
{
fclose(fp);
return 1;
}
return 0;
}
err_report_和_exit的一个简单实现是:
特定于GCC的位意味着您可以获得与直接使用printf相同级别的格式错误报告
这段代码以一个更大的包为模型,该包系统地使用err_u作为函数前缀。在该包中,此函数将是err_error。这就是为什么它是err_uuu而不是error_uuuuu——尽管解释键入比修复它花费的时间更长。这个大的包包含在文件stderr.c和stderr.h中,尽管有一个论点认为它使用std前缀是如履薄冰。然而,这是我的标准错误报告包
FILE* openCatalog(char catalogname[])
作为char*catalogname,这会更好,因为实际上并没有传递数组,而是得到一个指向字符的指针。这是C语言的一个有趣的小怪癖。当它起作用时,我发现提醒你只得到一个指针是非常受欢迎的
fopen3返回一个FILE*对象。不能将文件*分配给char[]变量
如果要在fopen3调用中使用catalogname变量,只需使用它:
FILE *f = fopen(catalogname, "r");
在这种情况下,fopen是一个函数指针。您不是将上一个fopen调用的返回值与0进行比较,而是将函数指针与0进行比较。那不是你想要的
return 1;
您将函数声明为返回一个文件*,这是您应该返回的,而不是一个整数
重新编写的版本如下所示:
FILE* openCatalog(char *catalogname) {
FILE *f = fopen(catalogname, "r");
if (!f)
perror("Unable to open file");
return f;
}
这仍然是错误的。如果文件已成功打开,则会使其悬空而不关闭-1@Richard:该函数的原型是返回文件*。“当然,它仍然是开放的。”萨诺尔德看了看他重新制作的OP的功能。它返回一个int而不是文件*@Richard:在另一种情况下,检查版本时,在成功的情况下,我仍然看到fclose调用…在C中不允许创建具有相同名称的新变量。
FILE *f = fopen(catalogname, "r");
if(fopen != 0)
return 1;
FILE* openCatalog(char *catalogname) {
FILE *f = fopen(catalogname, "r");
if (!f)
perror("Unable to open file");
return f;
}