Search code examples
cfilecstring

Reading specific line from file


I am trying to read a specific line from a file using the code below.

char *getlinenum(char *filename, int lnum)
{
    FILE *f;
    int i;
    char *linebuf = NULL, *tmp = NULL;
    if ((f = fopen(filename, "r")) != NULL)
    {
        linebuf = (char *)malloc(2048);
        memset(linebuf, 0, 2048);
        for (i = 0; i < lnum; i++)
        {
            if (fscanf(f, "%[^\n]\n", linebuf) == EOF)
            {
                free(linebuf);
                fclose(f);
                printf("Returning NULL\n");
                return NULL;
            }
        }
        //tmp = strdup(linebuf);
        //free(linebuf);
        fclose(f);
        return linebuf;
    }
    return NULL;
}

No matter what, this is always returning just an empty (zero) string. Any issues you see? Here is the test file:

/home/mainframe/b
/home/mainframe/dead.letter
/home/mainframe/.bash_history
/home/mainframe/a
/home/mainframe/f
/home/mainframe/e
/home/mainframe/c
/home/mainframe/g
/home/mainframe/.ssh/authorized_keys
/home/mainframe/.ssh
/home/mainframe/d

I don't really understand where it could end up with a zero string (not a nullpointer).


Solution

  • This code is working for me (made no changes except removing uncesessary tmp variable)

    One issue is if 0 is passed, the for loop never enters. Just change it to <= and/or add another if-statement at the beginning:

    if( lnum <= 0 ) 
      return NULL;
    

    to catch this issue.

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    char *getlinenum(char *filename, int lnum)
    {
        FILE *f;
        int i;
        char *linebuf = NULL;
    
        if( lnum <= 0 ) 
          return NULL;
    
        if ((f = fopen(filename, "r")) != NULL)
        {
            linebuf = (char *)malloc(2048);
            memset(linebuf, 0, 2048);
            for (i = 0; i <= lnum; i++)
            {
                if (fscanf(f, "%[^\n]\n", linebuf) == EOF)
                {
                    free(linebuf);
                    fclose(f);
                    printf("Returning NULL\n");
                    return NULL;
                }
            }
            free(linebuf);
            fclose(f);
            return linebuf;
        }
        return NULL;
    }
    
    int main()
    {
       printf("%s\n", getlinenum("input.txt", 2));
       return 0;
    }
    

    Output:

    /home/mainframe/dead.letter