getline 不将字符串存储在变量中

getline doesn't store the string in the variable

我编写了一个函数来打开用户指定名称的文件:

#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);
}

getrep 函数只是确保用户给出 Y 或 N 或 y 或 n 作为答案。这是清除函数:

#include <stdio.h>

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

这是我 运行 程序得到的结果:

Name of the file: Data.dat

The name of the file is: (null)

Can't open the file. Want to retry ?

当我使用调试器 gdb 并在输入文件名后打印 nfile 的值时,它仍然是 0x0,即 NULL。 (您可能已经注意到我没有为 nfile 分配内存,但我将此变量初始化为 NULL,以便 getline 为我完成它。我使用 getline 而不是 gets 因为它看起来更好,毕竟 ubuntu 16.04 讨厌得到)

我认为发生这种情况的原因是当要求用户输入名称时,这是由于 clear 函数中的 getchar() 造成的。因此,用户输入的名称被删除,nfile 在 getline 中什么也接收不到。我也尝试使用这个 clear 函数来代替:

#include <stdio.h>

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

不幸的是,我得到了同样的结果。我使用 fflush(stdin); 而不是 clear(); 但这次程序跳过 getline 不让用户输入任何内容。我还删除了 file: in printf("Name of the file: "); 之后的 space 但没有任何变化。

你能帮帮我吗?提前致谢!

问题出在 getline 调用中。

传入的第二个参数NULL不正确

应该是这样的:

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

根据 getlineman page,声明:

ssize_t getline(char **lineptr, size_t *n, FILE *stream);

If *lineptr is set to NULL and *n is set 0 before the call, then getline() will allocate a buffer for storing the line. This buffer should be freed by the user program even if getline() failed.

来自 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

由于您将 NULL 指针作为 n 参数传递,调用不会为您分配缓冲区。您需要显式传递指向已初始化为零的 size_t 变量的指针:

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