Search code examples
cstringgetline

getline doesn't store the string in the variable


I wrote a function that opens a file which name is given by the user:

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

void getfile(FILE** pfile)  
{
    void getrep(char*,char,char);
    void clear(void);
    char rep;
    char* nfile=NULL;
    printf("Name of the file: ");
    clear();
    nfile=NULL;
    getline(&nfile,NULL,stdin);
    printf("The name of the file is: %s\n",nfile);
    *pfile=fopen(nfile,"r");
    while(!*pfile)
    {
        printf("Can't open the file. Want to retry <Y/N> ? ");
        getrep(&rep,'Y','N');
        if(rep=='Y')
        {
            system("clear");
            free(nfile);
            nfile=NULL;
            printf("Name of the file: ");
            clear();
            getline(&nfile,NULL,stdin);
            printf("The name of the file is: %s\n",nfile);
            *pfile=fopen(nfile,"r");
        }
        else
            exit(-1);
    }
    free(nfile);
}

The getrep function simply ensures that the user gives Y or N or y or n as an answer. Here's the clear function:

#include <stdio.h>

void clear(void)
{
    char c;
    while((c=getchar())!=EOF && c!='\n');
}

Here's what I get when I run the program:

Name of the file: Data.dat

The name of the file is: (null)

Can't open the file. Want to retry ?

When I used the debugger gdb and printed the value of nfile after entering the file's name, it remains 0x0, i.e, NULL. (You might have noticed that I allocated no memory for nfile, but I initialized this variable to NULL so that getline will do it for me. I'm using getline instead of gets because it seems better and, after all, ubuntu 16.04 hates gets)

I believe the reason why this is happening is that when the user is asked to enter the name, it's due to the getchar() in the clear function. Thus the name entered by the user is erased, and the nfile receives nothing in getline. I also tried using this clear function instead:

#include <stdio.h>

void clear2(void)
{
    char c;
    while((c=getchar())!='\n');
}

Unfortunately, I get the same result. I used fflush(stdin); instead of clear(); but this time the program skips getline not letting the user enter anything. I also removed the space that comes after file: in printf("Name of the file: "); but nothing changes.

Could you please help me? Thanks in advance!


Solution

  • From the getline manual page`:

    If *lineptr is set to NULL and *n is set 0 before the call, then getline() will allocate a buffer for storing the line

    Since you pass a NULL pointers as the n argument, the call will not allocate a buffer for you. You need to explicitly pass a pointer to a variable of size_t that has been initialized to zero:

    char *nfile = NULL;
    size_t n = 0;
    getline(&nfile,&n,stdin);