我注意到在使用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)) {
...
答案 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的第一个参数(同样,你的编译器应该抱怨),因此,回到它的初始值。
建议:在编译器中使用更高级别的错误/警告并修复代码。