如何使用 feof 和 ferror for fgets(C 中的 minishell)[复制]

How to use feof and ferror for fgets (minishell in C) [duplicate]

提问人:Trouble-lling 提问时间:2/12/2014 最后编辑:HaveNoDisplayNameTrouble-lling 更新时间:5/23/2015 访问量:3342

问:

我已经编写了这个迷你外壳,但我不确定我是否正确控制了错误。我知道 fgets 可以返回 feof 和 ferror (http://www.manpagez.com/man/3/fgets/) 但我不知道如何使用它们。

我已经检查了 fgets 是否返回 null 指针(表示缓冲区的内容是 inditerminate),但我想知道如何使用 feof 和 ferror。

    #include <stdio.h>
    #include <stdlib.h> 
    #include <string.h> 
    #include <stdbool.h>    
    #define LINE_LEN  50
    #define MAX_PARTS  50 
    int main ()
    {
    char* token;
    char str[LINE_LEN];
    char* arr[MAX_PARTS];
    int i,j;
    bool go_on = true;

    while (go_on == true){
        printf("Write a line:('quit' to end) \n $:");
        fgets(str, LINE_LEN, stdin);

        if (str==NULL) {
            goto errorfgets;
        } else {
            size_t l=strlen(str);
            if(l && str[l-1]=='\n')
                str[l-1]=0;

            i=0;
            /* split string into words*/
            token = strtok(str, " \t\r\n");
            while( token != NULL ) 
            {
                arr[i] = token;
                i++;
                token = strtok(NULL," \t\r\n");
            }

            fflush(stdin);

            /* check if the first word is quit*/
            if (strcmp(arr[0],"quit")==0)
            {
                printf("Goodbye\n");
                go_on = false;
            } else {

                for (j=0; j < i; j++){
                printf("'%s'\n", arr[j]);       
                }   
            }
        }
    }

    return 0;
    errorfgets:
        printf("fgets didn't work correctly");
        return -1;
}
C fgets feof ferror

评论

5赞 Michael Burr 2/12/2014
@Digital_Reality:使用的一个合理情况是错误处理。goto
1赞 Digital_Reality 2/12/2014
@MichaelBurr可以通过调用一些清理函数来处理。不是吗?
1赞 Trouble-lling 2/12/2014
那么,如果我将其更改为 if (!fgets){ ....},我应该如何处理 feoh 和 ferror 可能的错误?
7赞 Michael Burr 2/12/2014
@Digital_Reality:也许吧,但通常确实是处理错误的最干净的方法(至少可以说是这样)。在示例中只有一个错误路径的函数中,这可能没什么大不了的,但是在任何错误条件下使用跳转到错误处理块的习惯习惯作为一般编码风格是很常见的。查看 eli.thegreenplace.net/2009/04/27/...goto

答:

3赞 cnicutar 2/12/2014 #1
fgets(str, LINE_LEN, stdin);

if (str==NULL) {
    goto errorfgets;
}

这不是检查 的返回值的方式。更重要的是,根据定义,在您的代码中永远不会。你想要这样的东西:fgetsstrNULL

if (!fgets(....)) }
    /* error handling. */
}
2赞 Amit 2/12/2014 #2

你可以像这样使用 feof。

#open a file
fd = fopen (testFile,"r+b");

#read some data from file 
fread (&buff, 1, 1, fd);
..
..
..
#To check if you are at the end of file
if (feof (fd))
{
    printf("This is end of file");
}else{
    printf("File doesn't end. Do continue...");
}
2赞 Grodriguez 2/14/2014 #3

首先,您的测试:

fgets(str, LINE_LEN, stdin);

[...]

if (str==NULL) {
    goto errorfgets;
}

是错误的。该参数按 value 传递,不能由 修改。相反,您应该检查返回的值(EOF 或错误返回)。strfgets()fgets()NULL

关于您的具体问题:不“返回”或.两者实际上都是函数(请参见手册页)。您可以按如下方式使用它:fgets()feofferrorfeof()ferror()

if (!fgets(str, LINE_LEN, stdin)) {
    /* fgets returns NULL on EOF and error; let's see what happened */
    if (ferror(stdin)) {
        /* handle error */
    } else {
        /* handle EOF */
    }
}