Ncurses程序正在退出,甚至没有创建窗口

Ncurses程序正在退出,甚至没有创建窗口,c,linux,gnu,ncurses,C,Linux,Gnu,Ncurses,我写了一个简单的C flashcard程序;它将文件名作为其第二个参数,然后逐行读取此文件,并使用ncurses将问题显示给用户,按enter键时显示答案,再次按刷新ncurses窗口,以便读取下一行。读取的文件是一个简单的TSV(尽管我编写它是为了使它可以是任何分隔符)。这是文件名为f.c: 注意:我使用了readline(),这是一个非C标准函数,因为这是一个我只会在POSIX系统上使用的个人项目,所以用fgets正确管理内存的头痛不值得 #包括 #包括 #包括 #包括 #包括 #包括 #定

我写了一个简单的C flashcard程序;它将文件名作为其第二个参数,然后逐行读取此文件,并使用ncurses将问题显示给用户,按enter键时显示答案,再次按刷新ncurses窗口,以便读取下一行。读取的文件是一个简单的TSV(尽管我编写它是为了使它可以是任何分隔符)。这是文件名为f.c:

注意:我使用了readline(),这是一个非C标准函数,因为这是一个我只会在POSIX系统上使用的个人项目,所以用fgets正确管理内存的头痛不值得

#包括
#包括
#包括
#包括
#包括
#包括
#定义DELIM“\t”
整数计数(字符*字符串,字符*值)
{
整数计数=0;
const char*tmp=字符串;
而(tmp=strstr(tmp,val))
{
计数++;
tmp++;
}
返回计数;
}
bool有效_文件(文件*流)
{
char*line=NULL;
尺寸透镜;
while(getline(&line,&len,stream)!=-1)
{
如果(计算occ(线、线)!=1)
{
返回false;
}
}
返回true;
}
int main(int argc,char*argv[])
{
如果(argc!=2)
{
fprintf(stderr,“必须提供文件名”);
退出(退出失败);
}
如果(!access(argv[1],F_OK)==0)
{
fprintf(stderr,“第二个参数中提供的文件不存在\n”);
退出(退出失败);
}
文件*stream=fopen(argv[1],“r”);
如果(!有效的_文件(流))
{
fprintf(stderr,“提供的文件格式不正确:一行缺少一组分隔值或注意到太多字段”);
退出(退出失败);
}
initscr();
noecho();
原始();
char*line=NULL;
尺寸透镜;
while(getline(&line,&len,stream)!=-1)
{
char*qn=strtok(行,DELIM);
char*ans=strtok(NULL,DELIM);
字符c;
printw(“问题:\n\t%s\n答案:\n\t…\n\n”,qn);
而((c=getch())!=10);
刷新();
移动(0,0);
printw(“问题:\n\t%s\n答案:\n\t%s\n\n”,qn,ans);
而((c=getch())!=10);
刷新();
移动(0,0);
}
endwin();
返回0;
}
我使用以下方法编译它:

gcc f.c -o fc -lncurses
…当然,安装了正确的库

然后,我使用这个文件test.txt作为示例:

What is my name?    Teddy Roosevolt
What is my name?    Teddy Roosevolt
Where am I from?    USA
What is my ethnicity?   Caucasian
What is my nationality? British
What is my name?    Teddy Roosevolt
Where am I from?    USA
What is my ethnicity?   Caucasian
What is my nationality? British
What is my name?    Teddy Roosevolt
Where am I from?    USA
What is my ethnicity?   Caucasian
What is my nationality? British
Where am I from?    USA
What is my ethnicity?   Caucasian
What is my nationality? British
然后,我运行了它:

./fc test.txt
我什么也没得到,甚至连一个错误都没有,一点也没有。相反,程序立即运行并立即退出。我在格式不好的文件上测试了它,然后在无错误的flashcard文件上测试了它-格式不好的文件会产生所有正确的错误,这告诉我,它不起作用的原因与主文件开头的代码块无关——检查文件是否有效——我认为这与ncurses部分有关——但我不知道是什么原因


谢谢你的帮助。

其实很简单,与课程无关:

你从不倒带你的文件

您的
valid_file
函数读取文件中的所有数据,不为
main
中的循环留下任何内容

由于在执行该功能后从未重置文件位置,因此不会执行
main
中的循环,因为
readline
没有剩余内容可供读取,因此程序将结束

您必须添加
fseek(流,0,SEEK\u集)
有效\u文件的末尾
返回true之前

还要注意的是,您从未
free
内存
readline
分配给您,您必须在每次调用后执行此操作,并且还将
指针重置为NULL和
len
为0,以使其分配新的缓冲区

否则将导致内存泄漏。

如果您的文本文件很小,这可能不明显,但这仍然是一种糟糕的编程实践

我知道Roosevolt不是英国人,只是因为我是英国人,而最初的“test.txt”是对我个人信息的测试,所以我找到并替换了我不想共享的任何信息。与您的问题无关:您应该始终检查
fopen
的返回值。仅仅因为文件在调用
access
期间存在,并不意味着
fopen
不会失败。这就像一个符咒,谢谢:)我添加了fseek,使用了free(line),line=NULL和len=0每次使用getline,它都工作得很好。