fgets - 考虑空字符

问题描述

使用 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(强调我的):

  1. fgets 函数读取的字符数至多少于 n 指定的字符数 [...] 读取最后一个字符后立即写入空字符进入数组。
  2. [如果发生错误] 返回空指针。

因此,正确的用法是使用数组的完整大小检查返回值。

char buf[100];
if (fgets(buf,sizeof buf,stdin) == NULL) /* all bets are off */;