#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> 。
有解决方法吗?
答案 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 :您对printf
内if( fp == NULL )
的来电无效。 printf
期望第一个参数是格式,而不是输出流。我想你想打电话给fprintf
。
最后,为了正确检测EOF
条件中的while
,您必须将ch
声明为int
。 EOF
可能不一定适合char
,但它适合int
(而getc
也会返回int
)。您仍然可以使用%c
打印它。
答案 2 :(得分:0)
您应该使用google,或者查看Unix / Linux手册页或VisualStudio文档中的函数,而不是询问如何使用fgets()。 C,C ++和许多类对象中有数百个函数。您需要首先弄清楚如何自己回答基础知识,以便您真正的问题有可能得到回答。
如果你是C新手,你肯定做了正确的实验,但是看看其他代码,了解代码编写的一些提示/技巧。