Неявное объявление «получает»

Я понимаю, что «неявное объявление» обычно означает, что функция должна быть помещена в начало программы перед ее вызовом или что мне нужно объявить прототип.
Однако 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);
   }
}

person Death_by_Ch0colate    schedule 01.12.2015    source источник
comment
Покажите свой код, пожалуйста.   -  person kaylum    schedule 02.12.2015
comment
Какой у тебя код? Как вы его компилируете и по какой причине используете gets?   -  person PSkocik    schedule 02.12.2015
comment
Посмотрите stackoverflow.com/help/mcve, чтобы узнать, как создать пример кода.   -  person mrhn    schedule 02.12.2015


Ответы (2)


Вы правы в том, что если вы включаете правильные заголовки, вы не должны получать предупреждение о неявном объявлении.

Однако функция gets() была удалена из стандарта C11. Это означает, что прототипа gets() в <stdio.h> больше нет. gets() раньше жил в <stdio.h>.

Причина удаления gets() хорошо известна: он не может защитить от переполнения буфера. Таким образом, вы никогда не должны использовать gets() и вместо этого использовать fgets() и позаботьтесь о завершающей новой строке, если таковая имеется.

person P.P    schedule 01.12.2015
comment
(Если вы заинтересованы) Странная часть заключается в том, что даже несмотря на то, что он выдает ошибку, он все еще может работать нормально. - person Death_by_Ch0colate; 02.12.2015
comment
Вероятно, это потому, что в библиотеках все еще есть функция, возможно, чтобы избежать взлома древнего кода. Но ни один новый код не должен использовать gets(). - person P.P; 02.12.2015

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);
    }
}
person chqrlie    schedule 01.12.2015
comment
если вы используете gets, включите ‹stdio.h›, но, как все говорили, вы подвергаете свою программу переполнению буфера и эксплуатации. Используйте его, только если вы тестируете эксплойт с помощью этой функции. - person Samir Ouldsaadi; 26.04.2018
comment
@chqrlie Разве sizeof buf или sizeof file_name не хватает скобок? И почему вам нужно, чтобы размер имел внешний параметр mygets вместо того, чтобы делать size=sizeof(buf) внутри вашей функции mygets? - person SebMa; 13.05.2020
comment
@SebMa: круглые скобки требуются только в том случае, если аргумент sizeof является типом. Для выражения sizeof ведет себя как префиксный оператор. Я использую необязательные скобки только тогда, когда использую sizeof в таком выражении, как sizeof(*buf) * 10, но даже в этом выражении скобки необязательны и избыточны. - person chqrlie; 13.05.2020
comment
@SebMa: что касается аргумента size для mygets, он необходим, потому что размер массива, на который указывает buf, не может быть определен из самого указателя. sizeof(buf) - это просто размер указателя, а не массива. - person chqrlie; 13.05.2020