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

时间:2016-05-20 11:54:35

标签: c string getline

我编写了一个函数,用于打开一个名称由用户提供的文件:

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

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

  

文件名:Data.dat

     

文件名是:(null)

     

无法打开文件。想重试?

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

我认为发生这种情况的原因是当要求用户输入名称时,这是由于clear函数中的getchar()。因此,用户输入的名称将被删除,并且nfile在getline中不会收到任何内容。我也尝试使用这个清晰的功能:

#include <stdio.h>

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

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

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

2 个答案:

答案 0 :(得分:3)

问题出在getline来电。

传入的第二个参数是NULL,这是不正确的。

相反它应该是这样的:

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

根据getline的{​​{3}},声明:

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

如果* lineptr设置为NULL并且* n在调用之前设置为0,则   getline()将分配一个缓冲区来存储该行。这个缓冲区   即使getline()失败,也应该被用户程序释放。

答案 1 :(得分:3)

来自the getline manual page`

  

如果*lineptr设置为NULL并且*n在调用之前设置为0,那么getline()将分配一个缓冲区来存储该行

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

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