Search code examples
cfgets

Use of fgets() and gets()


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


int main() {
   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"); // is for read mode

   if (fp == NULL) {
      printf(stderr, "There was an Error while opening the file.\n");
      return (-1);
   }

   printf("The contents of %s file are :\n", file_name);

   while ((ch = fgetc(fp)) != EOF)
         printf("%c",ch);

   fclose(fp);
   return 0;
}

This code seems to work but I keep getting a warning stating "warning: this program uses gets(), which is unsafe."

So I tried to use fgets() but I get an error which states "too few arguments to function call expected 3".

Is there a way around this?


Solution

  • Yes: fgets expects 3 arguments: the buffer (same as with gets), the size of the buffer and the stream to read from. In your case your buffer-size can be obtained with sizeof file_name and the stream you want to read from is stdin. All in all, this is how you'll call it:

    fgets(file_name, sizeof file_name, stdin);
    

    The reason gets is unsafe is because it doesn't (cannot) know the size of the buffer that it will read into. Therefore it is prone to buffer-overflows because it will just keep on writing to the buffer even though it's full.

    fgets doesn't have this problem because it makes you provide the size of the buffer.

    ADDIT: your call to printf inside the if( fp == NULL ) is invalid. printf expects as its first argument the format, not the output stream. I think you want to call fprintf instead.

    Finally, in order to correctly detect EOF in your while-condition you must declare ch as an int. EOF may not necessarily fit into a char, but it will fit in an int (and getc also returns an int). You can still print it with %c.