问题描述
使用 int scanf(const char *format,...)
扫描用户输入时,我会读取比字符串大小少一个字符,因为字符串的最后一个字符必须是 null character \0
。>
char str[10];
scanf("%9s",str); /* take \0 into account */
但是当我使用 char *fgets(char *str,int n,FILE *stream)
时,我不知道应该如何指定 n
。大多数在线教程将其设置为 sizeof(str)
,但有人告诉我应该是 sizeof(str) - 1
。
那么如何防止缓冲区溢出?像这样:
char str[10];
fgets(str,10,stdin);
或者我应该这样做:
char str[10];
fgets(str,9,stdin);
解决方法
参见C11 7.21.7.2(强调我的):
-
fgets
函数读取的字符数至多少于n
指定的字符数 [...] 读取最后一个字符后立即写入空字符进入数组。 - [如果发生错误] 返回空指针。
因此,正确的用法是使用数组的完整大小并检查返回值。
char buf[100];
if (fgets(buf,sizeof buf,stdin) == NULL) /* all bets are off */;