C Fgets如何防止用户超过Maxsize?

C Fgets如何防止用户超过Maxsize?,c,fgets,C,Fgets,我使用fgets从用户那里获取一个名称,并将其放入一个char数组中。 如果用户在fgets中给出了beyondmaxsize,那么我的程序就有问题了。我认为如果用户超过maxsize,则返回NULL。但事实并非如此。如何控制此错误 当然,我可以将maxsize设置为200甚至更多。但我认为这不是一个很好的解决方案 我在if语句中使用了fgets,如果==NULL,我会打印一个错误,但正如我已经告诉过的那样,如果用户超过maxsize,这将不起作用 fgets(name, 20, stdin)

我使用fgets从用户那里获取一个名称,并将其放入一个char数组中。 如果用户在
fgets
中给出了beyond
maxsize
,那么我的程序就有问题了。我认为如果用户超过
maxsize
,则返回
NULL
。但事实并非如此。如何控制此错误

当然,我可以将
maxsize
设置为200甚至更多。但我认为这不是一个很好的解决方案

我在
if
语句中使用了
fgets
,如果
==NULL
,我会打印一个错误,但正如我已经告诉过的那样,如果用户超过
maxsize
,这将不起作用

 fgets(name, 20, stdin);

就fgets而言,这不是一个错误。当您执行
fgets(name,20,stdin)
时,它只需从标准输入中读取最多19个字符(如果其中一个字符是
'\n'
),则读取的字符数会更少。剩下的字符将保留在stdin中,下一次调用输入函数时将拾取它们

您可以通过检查对
fgets
的成功调用来检测这种情况,其中字符串不包含
'\n'

if (!fgets(name, 20, stdin)) {
    // fgets failed; handle error
}
if (!strchr(name, '\n')) {
    // no newline in 'name'; a partial line was read
}
然后,您可以选择分配一个更大的缓冲区,或者丢弃该行的其余部分,或者向用户投诉

当然,我可以将maxsize设置为200甚至更多。但我认为这不是一个很好的解决方案

这种方法并不坏

创建一些允许大行的
my_gets()
,可以对用户输入进行无限制的内存资源控制,这可能是黑客的攻击。一个巨大的行更有可能是错误的输入或恶意代码黑客

我会使用一个大的,但合理的上限。然后检测诸如错误/恶意之类的大型线路

请注意,文本文件行具有环境限制。因此,证明巨大的缓冲是没有意义的

实现应支持包含至少254个字符的行的文本文件,包括终止新行字符。宏BUFSIZ的值应至少为256。C11§7.21.2 7

#定义我的BUFSIZE((BUFSIZE<4096)?BUFSIZE:4096)
字符名[MY_BUFSIZE+2];
if(fgets(名称、名称大小、标准输入)){
如果(strlen(name)>=MY_BUFSIZE)太长错误();

注意:输入异常读取空字符会导致问题。fgets()可能允许最多
maxsize+1
输入,如果输入的名称长度超过
maxsize
则不接受输入。此外,请尝试
get()
和/或
get\s()
。不确定它是否与
fgets(,.stdin)完全相同
,它们是console-i/o的特殊功能。谢谢。我要尝试一下。我知道这不是一个错误,但当用户超过maxsize时,我会遇到一个问题,因为我在fgets之后扫描了一个数字!@Psz_13警告,没有\n的事实可能意味着你有更多的内容要阅读,但这不是强制性的,你可以在没有\n的情况下到达EOF。@bruno T是的,但就C输入模型而言,这仍然是一部分行。只是当您达到EOF时,您永远无法得到完整的行(以
\n
结尾)。
ssize\t getline(char**lineptr,size\t*n,FILE*stream)
是一种实用的替代方案fgets@brunoPOSIX不是标准的C?POSIX扩展了C并为符合POSIX的系统添加了功能。Linux有,windows没有。当然,除非您使用WSL。
#define MY_BUFSIZE ((BUFSIZE < 4096) ? BUFSIZE : 4096)

char name[MY_BUFSIZE + 2];
if (fgets(name, sizeof name, stdin)) {
  if (strlen(name) >= MY_BUFSIZE) Too_long_error();