【问题标题】:Implicit declaration of 'gets''gets' 的隐式声明
【发布时间】:2016-03-06 00:45:29
【问题描述】:

我了解“隐式声明”通常意味着函数必须在调用它之前放在程序的顶部,或者我需要声明原型。
但是,gets 应该在 stdio.h 文件中(我已经包含在内)。
有没有办法解决这个问题?

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
   char ch, file_name[25];
   FILE *fp;

   printf("Enter the name of file you wish to see\n");
   gets(file_name);
   fp = fopen(file_name,"r"); // read mode
   if( fp == NULL )
   {
      perror("Error while opening the file.\n");
      exit(EXIT_FAILURE);
   }
}

【问题讨论】:

  • 请出示您的代码。
  • 你的密码是什么?你是如何编译它的,你使用gets的原因是什么?
  • 查看stackoverflow.com/help/mcve 获取有关如何生成示例代码的灵感

标签: c linux gets


【解决方案1】:

你是对的,如果你包含正确的标题,你不应该得到隐式声明警告。

但是,函数 gets() 已从 C11 标准中删除。这意味着&lt;stdio.h&gt; 中不再有gets() 的原型。 gets() 曾经&lt;stdio.h&gt;

删除gets() 的原因是众所周知的:它不能防止缓冲区溢出。因此,您永远不应该使用 gets() 并改用 fgets() 并注意尾随换行符(如果有)。

【讨论】:

  • (如果您不熟悉)奇怪的部分是,即使它给出了错误,它仍然能够正常运行。
  • 这可能是因为库仍然具有该功能,可能是为了避免破坏古老的代码。但是任何新代码都不应该使用gets()
【解决方案2】:

gets() 已从 C11 标准中删除。不要使用它。 这是一个简单的替代方案:

#include <stdio.h>
#include <string.h>

char buf[1024];  // or whatever size fits your needs.

if (fgets(buf, sizeof buf, stdin)) {
    buf[strcspn(buf, "\n")] = '\0';
    // handle the input as you would have from gets
} else {
    // handle end of file
}

您可以将此代码包装在一个函数中,并将其用作gets 的替代品:

char *mygets(char *buf, size_t size) {
    if (buf != NULL && size > 0) {
        if (fgets(buf, size, stdin)) {
            buf[strcspn(buf, "\n")] = '\0';
            return buf;
        }
        *buf = '\0';  /* clear buffer at end of file */
    }
    return NULL;
}

并在您的代码中使用它:

int main(void) {
    char file_name[25];
    FILE *fp;

    printf("Enter the name of file you wish to see\n");
    mygets(file_name, sizeof file_name);
    fp = fopen(file_name, "r"); // read mode
    if (fp == NULL) {
        perror("Error while opening the file.\n");
        exit(EXIT_FAILURE);
    }
}

【讨论】:

  • 如果你使用gets include 但就像每个人都说你把你的程序用于缓冲区溢出和利用。仅当您使用此函数测试漏洞利用案例时才使用它。
  • @chqrlie sizeof bufsizeof file_name 不是缺少括号吗?以及为什么你需要在你的mygets 函数中使用mygets 的外部参数而不是size=sizeof(buf)
  • @SebMa:只有当sizeof 的参数是类型时才需要括号。对于表达式,sizeof 表现为前缀运算符。当我在 sizeof(*buf) * 10 等表达式中使用 sizeof 时,我只使用可选括号,但即使在此表达式中,括号也是可选且多余的。
  • @SebMa:关于mygetssize 参数,这是必需的,因为无法从指针本身确定buf 固定到的数组的大小。 sizeof(buf) 只是指针的大小,而不是数组的大小。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-01
  • 2021-01-20
  • 1970-01-01
  • 2011-02-21
相关资源
最近更新 更多