【问题标题】:getline doesn't store the string in the variablegetline 不将字符串存储在变量中
【发布时间】:2016-09-17 16:24:47
【问题描述】:

我写了一个函数,可以打开一个文件名由用户指定:

#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 作为答案。这是 clear 函数:

#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 而不是 get,因为它看起来更好,毕竟 ubuntu 16.04 讨厌 get )

我认为发生这种情况的原因是,当要求用户输入名称时,这是由于 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: "); 后面的空格,但没有任何变化。

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

【问题讨论】:

  • 不要在另一个函数中声明函数。这可能会导致混淆,您必须在每个调用它们的函数中都这样做。
  • @iharob 非常感谢。确实,您是对的,这是要避免的事情,我们应该改用标题。但是,getfile、getrep 和 clear 是同一个个人“库”的函数,这就是我不这样做的原因。

标签: c string getline


【解决方案1】:

问题出在getline 电话中。

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

应该是这样的:

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

根据man pagegetline,声明:

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

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

【讨论】:

  • getline(&amp;nfile,0,stdin);getline(&amp;nfile,NULL,stdin); 在这里是一样的。
  • 我将避免进入 NULL 与 0 的细微差别,这是不一样的! ;)
  • 非常感谢。我的错误是我没有正确阅读如何使用 getline。我现在要纠正我的程序并测试它。
  • 你是对的。 getline 现在正在工作。非常感谢!
  • @t0mm13b 关键字是“这里”。无论如何,我发表评论时您的回答不正确。
【解决方案2】:

来自the getline manual page`

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

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

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

【讨论】:

  • 非常感谢。我的错误是我没有正确阅读如何使用 getline。我现在要纠正我的程序并测试它。
  • 你是对的。 getline 现在正在工作。非常感谢!
猜你喜欢
  • 2016-08-27
  • 1970-01-01
  • 2022-11-02
  • 2012-02-13
  • 2018-12-01
  • 1970-01-01
  • 2014-07-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多