使用fgets()和gets()

时间:2013-11-02 23:56:39

标签: c fgets

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

此代码似乎有效但我不断收到警告,说明“警告:此程序使用gets(),这是不安全的。”

所以我尝试使用fgets()但是我收到一个错误,指出“函数调用的参数太少”#3>

有解决方法吗?

3 个答案:

答案 0 :(得分:2)

首先:永远不要使用gets() .. 会导致缓冲区溢出

第二:向我们展示你如何使用fgets() ..正确的方法应该是这样的:

fgets(file_name,sizeof(file_name),fp); // if fp has been opened
fgets(file_name,sizeof(file_name),stdin); // if you want to input the file name on the terminal

// argument 1 -> name of the array which will store the value
// argument 2 -> size of the input you want to take ( size of the input array to protect against buffer overflow )
// argument 3 -> input source

<强>供参考:

fgets通过在末尾添加\0字符将整个输入转换为字符串..

如果有足够的空间,那么fgets也会从你的输入(stdin)获得\n ..去除\n并仍然将整个输入作为一个字符串,做到这一点:

   fgets(file_name,sizeof(file_name),stdin);

   file_name[strlen(file_name)] = '\0';

答案 1 :(得分:1)

是:fgets需要3个参数:缓冲区(与gets相同),缓冲区大小和要读取的流。在您的情况下,您可以使用sizeof file_name获取缓冲区大小,并且您要读取的流是stdin。总而言之,这就是你所说的:

fgets(file_name, sizeof file_name, stdin);

gets不安全的原因是因为它不会(不能)知道它将读入的缓冲区的大小。因此它很容易出现缓冲区溢出,因为即使它已满,它也会继续写入缓冲区。

fgets没有这个问题,因为它会让你提供缓冲区的大小。

ADDIT :您对printfif( fp == NULL )的来电无效。 printf期望第一个参数是格式,而不是输出流。我想你想打电话给fprintf

最后,为了正确检测EOF条件中的while,您必须将ch声明为intEOF可能不一定适合char,但它适合int(而getc也会返回int)。您仍然可以使用%c打印它。

答案 2 :(得分:0)

您应该使用google,或者查看Unix / Linux手册页或VisualStudio文档中的函数,而不是询问如何使用fgets()。 C,C ++和许多类对象中有数百个函数。您需要首先弄清楚如何自己回答基础知识,以便您真正的问题有可能得到回答。

如果你是C新手,你肯定做了正确的实验,但是看看其他代码,了解代码编写的一些提示/技巧。