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

3.4k views Asked by At

I've written this minishell but I'm not sure I'm making a correct control of the errors. I know fgets can return feof and ferror (http://www.manpagez.com/man/3/fgets/) but I don't know how to use them.

I've checked if fgets returns a null pointer (which indicates the content of the buffer is inditerminate) but i would like to know how to use feof and 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;
}
3

There are 3 answers

0
Grodriguez On BEST ANSWER

First of all, your test:

fgets(str, LINE_LEN, stdin);

[...]

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

is wrong. The str parameter is passed by value and cannot be modified by fgets(). Instead, you should be checking the value returned by fgets() (returns NULL on EOF or error).

Regarding your specific question: fgets() does not "return" feof or ferror. Both feof() and ferror() are actually functions (see the man pages). You would use this as follows:

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 */
    }
}
0
Amit On

You can use feof like this.

#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...");
}
0
cnicutar On
fgets(str, LINE_LEN, stdin);

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

That's not how you check the return value of fgets. What's more, in your code str will never be NULL by definition. You want something like:

if (!fgets(....)) }
    /* error handling. */
}