19

I understand that an 'implicit declaration' usually means that the function must be placed at the top of the program before calling it or that I need to declare the prototype.
However, gets should be in the stdio.h files (which I have included).
Is there any way to fix this?

#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);
   }
}
3
  • 2
    Show your code please. Commented Dec 1, 2015 at 22:37
  • 1
    What's your code? How are you compiling it, and what is your reason for using gets? Commented Dec 1, 2015 at 22:38
  • 1
    Look at stackoverflow.com/help/mcve for inspiration on how to produce example code Commented Dec 1, 2015 at 22:38

2 Answers 2

28

You are right that if you include proper headers, you shouldn't get the implicit declaration warning.

However, the function gets() has been removed from C11 standard. That means there's no longer a prototype for gets() in <stdio.h>. gets() used to be in <stdio.h>.

The reason for the removal of gets() is quite well known: It can't protect against the buffer overrun. As such, you should never use gets() and use fgets() instead and take care of the trailing newline, if any.

Sign up to request clarification or add additional context in comments.

2 Comments

(If you are inetersted) The weird part is, even though it gives the error it is still able to run just fine.
That's probably because the libraries still have the function, possibly to avoid breaking ancient code. But no new code should ever use gets().
18

gets() was removed from the C11 standard. Do not use it. Here is a simple alternative:

#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
}

You can wrap this code in a function and use that as a replacement for 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;
}

And use it in your code:

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);
    }
}

4 Comments

if you use gets include <stdio.h> but like everyone said you're putting your program for a buffer overflow and exploitation. Use it only if you're testing an exploit case with this function.
@chqrlie Isn't sizeof buf or sizeof file_name missing parenthesis ? And why do you need the size has an external parameter of mygets instead of doing size=sizeof(buf) inside your mygets function ?
@SebMa: parentheses are only required when the argument of sizeof is a type. For an expression, sizeof behaves as a prefix operator. I only use optional parentheses when I use sizeof in an expression such as sizeof(*buf) * 10 but even in this expression, the parentheses are optional and redundant.
@SebMa: regarding the size argument for mygets, it is required because the size of the array pinted to by buf cannot be determined from the pointer itself. sizeof(buf) is just the size of the pointer, not that of the array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.