这是手册页中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
调用之后,有没有办法告诉输入有多长没有先初始化缓冲区?
感谢。
答案 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
此类代码使用黑客攻击调用未定义行为:在行开头的文件中滑动空字符。 (请参阅this和this以获得更好的解决方案,以消除潜在的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后没有读取其他字符 换行符(保留)或文件结束后。 空 在读入最后一个字符后立即写入字符 数组。