我编写了一个函数,用于打开一个名称由用户提供的文件:
#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: ");
但没有任何变化。
答案 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)
如果
*lineptr
设置为NULL并且*n
在调用之前设置为0
,那么getline()
将分配一个缓冲区来存储该行
由于您将NULL
指针作为n
参数传递,因此调用不会为您分配缓冲区。您需要显式传递指向已初始化为零的size_t
变量的指针:
char *nfile = NULL;
size_t n = 0;
getline(&nfile,&n,stdin);