fgets和错误处理有点麻烦

时间:2014-03-11 20:49:36

标签: c fgets

我最近开始学习C并且遇到了代码剪切的一点问题。

我想要在stdin上读取一个字符串,20个字符长,所以我选择了fgets。

这是我的代码:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
unsigned int length = 20;
char input_buffer[length];
fgets(input_buffer, length, stdin);
if(input_buffer == NULL)
    printf("Error, input too long");
else
    printf("%s", input_buffer);
return 0;
}

它编译没有任何错误,如果我输入一个短于20个字符的句子,一切都很好。但是当我尝试测试错误处理时,它失败了。

输出结果为:

peter@antartica ~/test % ./test    
Hello world, this is a very long test
Hello world, this i%      

我做错了吗?我认为fgets如果失败会返回一个NULL指针(这应该是这种情况)?

感谢您的帮助。

2 个答案:

答案 0 :(得分:5)

来自fgets reference

  

成功时,该函数返回str。

     

如果文件结尾是   在尝试读取字符时遇到,eof指示符是   设(feof)。如果在任何字符被读取之前发生这种情况,那么   返回的指针是一个空指针(并且str的内容保留   不变)。

     

如果发生读取错误,则错误指示符(ferror)为   设置并返回一个空指针(但指向的内容   str可能已经改变了。)

因此,如果到达文件结尾,它可能会返回NULL而不会产生错误。您可能需要查看ferror返回值以确定它。

请注意fgets()会自动在字符串末尾附加一个空字符(\0),这可能会导致字符串被截断,因为您指定了必须读取的字符数。如果找到超过length个字符的字符串,则呼叫不会失败。

答案 1 :(得分:2)

出错时,fgets() 返回 NULL,但缓冲区的内容不确定。

您正在检查缓冲区,而不是返回值。

尝试:

if ( fgets(input_buffer, length, stdin) == NULL )
{
    printf("Error, input too long");
}
else
{
    printf("%s", input_buffer);
}

好建议:总是使用{},即使对于单行块也是如此。它确实有助于避免错误并使代码更易于阅读。

编辑: +1 Mauren:实际上不会将太长的输入行视为错误,但会被默默地截断,因此您的整个概念无法按预期工作。如有疑问,请务必查看文档以了解您正在使用的功能。尝试man fgets - 在Unix-ish环境中的命令行上,或者如果处于紧张状态,请在Web搜索引擎中。 ;)