编译时GCC报错:error: unknown type name ‘FILE’。

10
我正在编写一个函数,它只是向文件中写入“hello”。我已经将其放在另一个文件中,并在程序中包含了它的头文件。但是gcc报错,错误信息如下:
``` error: unknown type name ‘FILE’. ```
以下是代码:
``` app.c: ```
#include <stdio.h>
#include <stdlib.h>
#include "write_hello.h"

int main() {
    FILE* fp;
    fp = fopen("new_file.txt", "w");
    
    write_hello(fp);
    
    return 0;
}

write_hello.h:

void write_hello(FILE*);

write_hello.c:

void write_hello(FILE* fp) {
    fprintf(fp, "hello");
    printf("Done\n");
}

使用gcc编译时出现以下情况:

harsh@harsh-Inspiron-3558:~/c/bank_management/include/test$ sudo gcc app.c 
write_hello.c -o app
write_hello.c:3:18: error: unknown type name ‘FILE’
 void write_hello(FILE* fp) {

8
write_hello.c中也包含了#include <stdio.h>FILE的定义在stdio.h中。 - Spikatrix
我注意到你正在使用sudo命令行调用gcc编译器。实际上,在编译文件时不需要使用sudo。最佳做法是删除sudo,并直接输入以下命令:gcc app.c - ScottK
1个回答

20

FILE在stdio.h中定义,您需要在每个使用它的文件中包含它。因此,write_hello.h和write_hello.c都应该包括它,并且write_hello.c还应该包括write_hello.h(因为它实现了在write_hello.h中定义的函数)。

此外,请注意,每个头文件通常定义一个同名的宏(大写字母),并在#ifndef、#endif之间将整个头文件包围起来。在C语言中,这可以防止头文件被#included两次。这称为“内部包含保护”(感谢Story Teller指出)。所有系统头文件(如stdio.h)都包含内部包含保护。所有用户定义的头文件也应包括内部包含保护,如下例所示。

write_hello.h

#ifndef WRITE_HELLO_H
#define WRITE_HELLO_H
#include <stdio.h>
void write_hello(FILE*);
#endif

write_hello.c

#include <stdio.h>
#include "write_hello.h"
void write_hello(FILE* fp){
    fprintf(fp,"hello");
    printf("Done\n");
}

注意,当您包含系统文件时,头文件名应放在<>中。这有助于编译器识别这些头文件是存储在基于您的开发环境的中央位置的系统头文件。

您自己的自定义头文件放在引号""中,通常在当前目录中找到,但可以通过包含路径或将目录添加到编译器搜索列表中的方式放置在其他位置。如果您使用像NetBeans这样的IDE或使用-I编译器选项直接构建它或通过makefile构建,则可以在项目中进行配置。


1
我认为你要找的术语是“内部包含保护”。 - StoryTeller - Unslander Monica
好的,我明白了,谢谢。但是在许多文件中反复使用stdio.h,这是否意味着stdio.h会被包含多次,或者stdio.h也有“内部包含保护”?谢谢。 - Harsh Dave
1
@HarshDave,是的,stdio.h 有一个内部包含守卫,所有标准包含文件也都有。第一次包含头文件时,它定义了守卫并包含其内容。第二次,守卫已经被定义,因此#ifndef 是 false,并且整个头文件被跳过。这是由C预处理器cpp在gcc编译器之前完成的。因此,在编译单元中只包含一次stdio.h。 - ScottK
@ScottK,感谢您先生。 - Harsh Dave

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接