如何确定用fgets()读取的字符数?

时间:2017-12-14 15:51:46

标签: c io fgets stdio

这是手册页中fgets()的描述:

char *fgets(char *s, int size, FILE *stream);
...

RETURN VALUE
  fgets() returns s on success, and NULL on error or  when  end  of  file
  occurs while no characters have been read.

它不遵循read的模式,它在失败时返回-1,并在成功时读取字节数。相反,它返回char*,失败时为NULL,成功时为s。这没有给我任何关于输入多长时间的信息。所以,如果我有这样的事情:

char input_buffer[256];
fgets(input_buffer, sizeof(input_buffer), stdin);

fgets调用之后,有没有办法告诉输入有多长没有先初始化缓冲区?

感谢。

2 个答案:

答案 0 :(得分:5)

  

如何确定用fgets()读取的字符数?

char *fgets(char *s, int size, FILE *stream);

检查strlen(s)返回值后使用fgets()

if (fgets(s, size, stream)) {
  printf("number of characters that were read: %zu\n", strlen(s));
} else if (feof(stream)) {
  printf("number of characters that were read:0 End-of-file\n");
} else  {
  printf("number of characters that were read unknown due to input error\n");
}

除非 null字符 '\0',因为strlen()会在附加的'\0'之前遇到strlen(s)功能。在这种情况下,fgets()之后的s会报告较小的值。

预先填充fgets()然后调用fgetc()有各种技巧,但尚未定义未读缓冲区的其余部分会发生什么。存在其他缺点。

如果 null字符作为有效输入流的一部分是一个问题,请使用getline()或类似fgets()的内容。

空字符是文本的常见情况是文本编码为UTF-16。当然代码不应该使用if (fgets(s, size, stream)) { size_t len = strlen(s); s[--len] = '\0'; // poor way to lop off the trailing \n, this could be UB } 来阅读该文本,但这需要先验知识。由于错误地假设文本文件是非空字符文本文件,因此许多以 text 编写的代码都以神秘的方式失败。

此外,即使文本文件被认为缺少空字符,以下代码会发生什么?

\n

此类代码使用黑客攻击调用未定义行为:在开头的文件中滑动空字符。 (请参阅thisthis以获得更好的解决方案,以消除潜在的fgets(char *s, int size, FILE *stream);

强大的代码不会假定文本格式正确并采取措施来检测异常。

迂腐:size < 2 Purchase存在病态问题。

答案 1 :(得分:3)

是的。如果成功,它始终为空终止。所以它将是strlen(buf)

来自标准7.21.7.2

  

char *fgets(char * restrict s, int n,FILE * restrict stream);   fgets函数最多读取的数量少于1   由n指向的流stream指定的字符   s指向的数组。 a后没有读取其他字符   换行符(保留)或文件结束后。 空   在读入最后一个字符后立即写入字符   数组。