警告:隐式声明函数'gets'; 你是不是想用'fgets'? [-Wimplicit-function-declaration]

6

我刚开始学编程。我在Ubuntu终端中编码。在编译一个使用gets()函数的程序时,我遇到了问题。

#include<stdio.h>

/*example of multi char i/p function*/
void main()
{
    char loki[10];
    gets(loki);
    printf("puts(loki)");
}

我遇到的错误是:
warning: 'implicit declaration of function ‘gets’; did you mean ‘fgets’? [-Wimplicit-function-declaration]

3
在Ubuntu中,打开终端并输入man gets - Basile Starynkevitch
9
“gets”函数已从标准库中移除!(在旧版本中存在,但被宣布为“危险”,随后被移除。)您应该使用编译器“建议”的“fgets(loki, 10, stdin);”来代替。 - Adrian Mole
2
编程小提示:确保你的 main 函数的返回类型为 int,并在成功退出时返回 0 :) - itzFlubby
3
如果你正在跟随一个使用 void main 的书籍,那么你应该阅读 C-FAQ 11.15 - Antti Haapala -- Слава Україні
2个回答

11

gets在C11中被移除了,因为它是不可能正确使用的。 gets不知道可以存储多少个字符到数组中并且会继续写入用户提供的所有字符,这导致程序具有未定义行为 - 崩溃,修改无关数据等。

解决方法是使用fgets,但要记住它会在缓冲区中保留一个换行符:

#include <stdio.h>

// example of multi char i/p function
int main(void)
{
    char loki[10];
    fgets(loki, 10, stdin);

    // now loki will have the new line as the last character
    // if less than 9 characters were on the line

    // we can remove the extra with `strcspn`:
    loki[strcspn(loki, "\n")] = 0;

    // this will print the given string followed by an extra newline.
    puts(loki);
}

8
在Ubuntu上,打开终端并运行man gets命令。它应该会显示gets(3) man页面。
那份文档用书面英语写道:

永远不要使用这个函数。

更一般地说,编程之前,请阅读文档。对于Linux上的C语言,可以考虑阅读man页面, 这份C参考手册, 多个C编程教程, 以及C11标准n1570
英文维基百科还提到了gets
最后,

警告:隐式声明函数‘gets’; 你是不是想用‘fgets’?[-Wimplicit-function-declaration]

对我来说很清楚,因为它是用英语写的。作为一个经验法则,请确保您的程序在没有警告的情况下编译。还可以阅读如何调试小程序

您可能会对理解首字母缩写RTFM和STFW感兴趣。

我通过阅读SunOS3手册(当时是纸质版,在工作中与我使用的Sun3/160工作站一起出售)从第1节到第9节学习了C和Unix编程(1985年)。

在阅读手册之前,您可以先阅读高级Linux编程


我刚开始我的编程之旅。然后我建议阅读SICP。在我的祖父眼中,即使在2019年,它仍然是最好的编程入门教材。另请参阅这些提示。SICP使用一些在职业生活中不太常用的编程语言(但请查看 Guile)并不重要:编程是关于概念,而不是编码。 您将通过SICP学习到的概念肯定会帮助您以后编写更好的C代码。当然也要阅读 http://norvig.com/21-days.html

注意:我是法国人(1959年出生),因此不是英语母语者。但我在读书方面接受过教育,包括在博士研究期间以及在高中和父母的教导下。当我在大学教授一些计算机科学的内容时,我告诉学生的第一件事就是阅读。永远不要因为阅读而感到羞耻。


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