gpt4 book ai didi

c - 编译错误

转载 作者:太空宇宙 更新时间:2023-11-04 05:29:46 25 4
gpt4 key购买 nike

我正在创建一个函数,它应该打开一个文件(catalogname [])。然而,每当我编译时,我都会遇到这两个我无法理解的错误。
a3.c:在函数“openCatalog”中:
a3.c:20:警告:来自不兼容指针类型的赋值
a3.c:22:警告:return使整数指针不带强制转换
这是我的代码:

FILE* openCatalog(char catalogname[])
{
catalogname = fopen ("*catalogname", "r");
if(fopen != 0)
{
return 1;
}
else
{
return 0;
}
}

提前感谢您提供的任何见解。

最佳答案

对这段代码的完整解释需要一段时间。
简要版本为:

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 *(文件流指针)。所以,让我们在此基础上对代码进行评论。
函数原型行是可以的,它可以是 强调该函数不会修改文件名,但这是一个改进,而不是一个错误修复的改变。
函数中的 char const catalogname[]类型是 catalogname。在函数的参数列表中,数组大致等同于指针。我通常会写 char *来强调在函数中,它是一个 FILE *openCatalog(char const *catalogname)变量。不过,使用您使用的数组表示法是100%合法的;使用指针表示法纯粹是我的风格偏好。
下一个可执行行有几个问题。对 char const *的函数调用在技术上并没有错,尽管它打开的是一个固定名称的文件,而不是变量 fopen()中指定的文件。要解决这个问题,需要删除引号。 *catalogname将给您一个字符而不是一个字符串,它将是文件名的第一个字符。所以,也删除 catalogname
这就使得 *返回一个值,实际上是一个 *,并将其分配给 fopen(),一个 FILE *。这是类型不匹配,编译器会发出警告。如第一次重写中所示,处理此问题的更正常方法是:
FILE *fp = fopen(catalogname, "r");

这解释了您的错误消息:
a3.c:20: warning: assignment from incompatible pointer type

我们不知道您的目录是文本文件还是二进制文件。如果它是一个二进制文件,那么如果您是在Windows上(在Windows上它确实很重要),那么您应该使用 catalogname来打开它,这在类Unix系统上也可以正常工作(在这里文本文件和二进制文件没有区别)。
代码中的下一行是条件:
if (fopen != 0)

这实际上检查函数 char *的函数指针是否为空。而且C标准保证在托管环境(您正在使用的环境)中,函数指针不会为空。因此编译器可以优化该测试以假定条件始终为真。
你真正需要的是测试结果:
if (fp != 0)

然后有两个返回语句,一个返回1,一个返回0。返回1的函数将引发有关将整数转换为指针的警告,因为该函数定义为返回 "rb"且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));

使用 FILE *fopen()意味着您还应该包括标题:
#include <errno.h>
#include <string.h>

代码应返回 errno中的文件流:
return fp;

总的来说,这会导致:
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);
}

如果函数的目的是检查是否可以打开文件进行读取,则上述问题基本相同。我首先展示的修改后的代码有点冗长。因为假定的目的是检查文件是否可以打开,所以调用代码应该负责处理“it cannot be open case”;它知道要生成哪种诊断。这是修订版的一个稍微紧凑的版本,但This的目标代码和上面的目标代码是相同的。
int openCatalog(char catalogname[])
{
FILE *fp = fopen(catalogname, "r");
if (fp != 0)
{
fclose(fp);
return 1;
}
return 0;
}

strerror()的一个简单实现是:
#include "errreport.h"
#include <stdio.h>
#include <stdlib.h>
#include <starg.h>

void err_report_and_exit(char const *format, ...)
{
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
exit(EXIT_FAILURE);
}

“errreport.h”头可能是:
#ifndef ERRREPORT_H_INCLUDED
#define ERRREPORT_H_INCLUDED

#ifdef __GNUC__
#define PRINTFLIKE(n,m) __attribute__((format(printf,n,m)))
#define NORETURN() __attribute__((noreturn))
#else
#define PRINTFLIKE(n,m) /* If only */
#define NORETURN() /* If only */
#endif /* __GNUC__ */

extern void err_report_and_exit(char const *format, ...) PRINTFLIKE(1,2) NORETURN();

#endif /* ERRREPORT_H_INCLUDED */

GCC特定的位意味着您可以获得与直接使用 fopen()相同级别的格式错误报告。
(此代码是在一个更大的包上建模的,该包系统地使用 err_report_and_exit()作为函数前缀。在那个包中,这个函数将是 printf()。这就是为什么它是 err_而不是 err_error()的原因——尽管这种解释比修复它花费的时间要长。这个大的包包含在文件 err_error_中,尽管有一个参数表明它使用 stderr.c前缀是无足轻重的。不过,这是我的标准错误报告包。)

关于c - 编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10467372/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com