fopen / fgets使用char *而不是FILE *,为什么这样做?

时间:2013-08-09 18:47:20

标签: c

我注意到在使用fopen和fgets时我在代码中使用了char*变量而不是FILE*变量,但我的代码可以运行。我想知道为什么会这样?我的代码的一部分如下。

...
char* filePath = ac->filepath;
char* line = malloc(sizeof(char) * MAX_CHAR_PER_LINE) ;
filePath = fopen(filePath, "r"); // we are assigning the result to a char*, not FILE*
if (filePath == NULL) {
    printf ("\n[%s:%d] - error opening file '%s'", __FILE__, __LINE__, filePath);
    printf ("\n\n");
    exit (1);
}

while ((fgets(line, MAX_CHAR_PER_LINE, filePath) != NULL)) {
...

2 个答案:

答案 0 :(得分:3)

char*FILE*都只存储一个内存地址。 C的输入相当弱(编辑:这是我的一个误解,请参阅下面的评论)所以它可以让你分配指针而不用担心他们指向的类型。

fopen返回FILE对象的地址,并将该地址存储在某处(在您的情况下,它位于char*中)。当您使用fgets中的地址时,它仍然具有FILE对象的地址,因此一切都将按预期工作。

答案 1 :(得分:1)

您的编译器非常宽松。它应该抱怨FILE * to char *转换无效。

无论如何,假设编译器接受这种隐式转换,答案很简单。 根据C标准,char *和void *指针可以毫无损失地保存任何指针值。 因此,您可以从SOMETYPE *转换为char *,然后从char *转换为SOMETYPE *,并获得最初具有的相同指针。 实际上,在大多数系统上,所有指针都是等效的,你可以自由地从一个指针转换到另一个指针。

FILE *是指针类型的小且不透明的值。可能是指向内部数据结构的实际指针,但这可能以不同方式实现(例如,它可能是转换为指针的UNIX文件描述符)。 STDIO函数只是期望你在fread / fwrite / fclose中使用与fopen相同的不透明FILE *值。

分配给filePath时,FILE *将转换为char *。 char *被转换为FILE *作为fgets的第一个参数(同样,你的编译器应该抱怨),因此,回到它的初始值。

建议:在编译器中使用更高级别的错误/警告并修复代码。