我开始学习用C语言编程我在参考代码的书中显示了一些gets()
的源代码,我的IDLE也识别它。但是在编译时,我的编译器并不同意它。
任何人都可以帮助我吗?我在main函数中使用gets()
并使用clang作为编译器。
答案 0 :(得分:5)
扩展我的评论:
首先,从不使用out
,出于任何原因,即使在玩具代码中也是如此。如果您在示例程序中看到它,请忽略该示例并继续。它在C99中已弃用,并在C2011中从标准库完全中删除,因为它是一个主要的安全漏洞。由这一功能引起的胃灼热值得打破30多年的遗留代码。
其次,在C89及更早版本中,如果编译器在看到声明或定义之前看到函数调用,它会假定函数返回gets()
- IOW,函数有一个隐式 int
声明。如果您稍后在同一个翻译单元中有一个定义函数,并且该函数返回int
,那么您没问题:
int
但是,如果int foo( void )
{
int x = bar(); // bar *implicitly* declared to return int
}
int bar( void ) // implicit declaration matches definition, we're good
{
return some_integer_value;
}
不返回bar
,则会收到错误,因为隐式int
声明与非{ - int
定义。
int
会返回gets()
,而不是char *
,因此隐式声明int
不正确,无论。
C99完全删除了隐式gets
声明 - 从那时起,所有函数必须在调用之前声明或定义。
修改强>
您获得该隐式声明错误的最可能原因是您的编译器已足够新,以至于它不再在int
中声明gets
。
答案 1 :(得分:1)
您正在收到类似&#34的消息;不允许隐式声明获取#34;出于同样的原因,你得到了消息"不允许my_undeclared_function的隐式声明"如果您尝试拨打my_undeclared_function
。目前,gets
不是标准的C库函数。
更详细地解释:在现代C中,如果你写
int main()
{
f();
}
int f()
{
return 0;
}
您通常会收到一条消息,例如"隐含的功能声明' f'在C99"中无效。曾几何时,如果你调用了一个函数,编译器还没有听说过(还),它假设它将是一个返回int
的函数,但是在C99中删除了这个假设。
另一方面,如果你写
#include <stdio.h>
int main()
{
char line[100];
printf("type something:\n");
fgets(line, sizeof(line), stdin);
printf("you typed: %s", line);
return 0;
}
您将不获取有关函数printf
和fgets
的消息。这些是函数,编译器已经听说过:它们的声明在<stdio.h>
。
但如果你写
#include <stdio.h>
int main()
{
char line[100];
printf("type something:\n");
gets(line);
printf("you typed: %s", line);
return 0;
}
您将再次收到有关函数gets()
的消息,因为gets
不是编译器听过的函数。它不是标准功能;它未在<stdio.h>
中声明。
现在,曾几何时,gets
是一个标准函数,它在<stdio.h>
中声明,但它是一个非常错误构思和危险的函数,所以它已从标准中删除。你读过的那本书推荐它已经过时了。
答案 2 :(得分:0)
你没有#include <stdio.h>
,就这么简单。
在C99中,如果您使用此确切代码,则会收到错误:
int main (void)
{
char buf[10];
gets(buf);
return 0;
}
包括stdio.h修复了这个问题。虽然值得注意的是,gets
在C99中被标记为过时的功能,并完全从C11中的语言中删除。所以下面的代码不会在标准C(C11)中编译:
#include <stdio.h>
int main (void)
{
char buf[10];
gets(buf);
return 0;
}
因此您可能会收到错误,因为您编译为标准C而不是C99。
(请注意,Windows Mingw编译器特别可能使用C11编译器,但使用C99标准库,因此您可以使用该编译器获得一些odd outcomes。)
有关详细信息,请参阅Why is the gets function so dangerous that it should not be used?。