【问题标题】:Little trouble with fgets and error handlingfgets 和错误处理的小麻烦
【发布时间】:2014-03-11 20:49:36
【问题描述】:

我最近开始学习C,遇到了一个代码被剪掉的小问题。

我想在标准输入上读取一个 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 指针(这里应该是这种情况)?

感谢您的帮助。

【问题讨论】:

  • 请缩进您的代码。
  • 如果您从stdin 中读取20 个字符,您可能输入的是20 + 1 '\n',因此代码需要存储21 char。而字符串需要'\0',所以现在考虑unsigned int length = 20+1+1;

标签: c fgets


【解决方案1】:

来自fgets reference

成功时,函数返回str。

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

如果发生读取错误,错误指示符 (ferror) 为 set 并返回一个空指针(但由 str 可能已更改)。

因此它可能会返回NULL 而不会在到达文件末尾时产生错误。您可能需要查看ferror 返回值才能确定。

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

【讨论】:

    【解决方案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 环境中的命令行上,或者如果在紧要关头,在网络搜索引擎中。 ;)

    【讨论】:

    • 这实际上是fgets() 的好处:您可以遍历整个文件来读取其中的一小部分。
    • 谢谢,我没有意识到,但这只是合乎逻辑的,我会更深入地研究命令。您的示例代码认为,也会产生我的错误。我会尝试使用 ferror()。谢谢
    • @Mauren:如果我再花几秒钟的时间思考一下,我会记得的。我实际上在我自己的 C 库中实现了 fgets()。 ;-) 我的两个讨厌的习惯:一,我在编译器运行时回答 SO 问题,即总是在运行。第二,一旦我发现第一个错误,我通常认为案例已关闭,假设那里只有一个错误。 ;-) 您发现了第二个错误,因此应归功于信用。
    猜你喜欢
    • 2012-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-08
    相关资源
    最近更新 更多