2013-03-12 42 views
0

所以,这是我的问题。我使用的是ncurses,当我按下向上或向下按钮时,它会显示向上的箭头,所以我希望进入我的while循环,并进一步输入。问题是,这个过程中的变量输入变为NULL并且它存在。这是为什么?我想要的是打印或向下箭头,程序正常进行。变量在输入前被随机变为空

int ch; 
char input[100]; 
initscr(); 
raw(); 
keypad(stdscr, TRUE); 
noecho(); 
ch = getch(); 
if(ch== KEY_UP) 
    printf("\nUp Arrow"); fflush(stdout); 

if(ch== KEY_DOWN) 
    printf("\ndown Arrow");fflush(stdout); 

endwin(); 
+1

“输入”在哪里定义? – templatetypedef 2013-03-12 03:36:31

+0

@templatetypedef立即检查 – NoNameY0 2013-03-12 03:42:23

+0

请注意,尽管有缩进,两个'fflush(stdout);'调用都是无条件的。你需要大括号(或逗号代替分号 - ick!)以使它们成为有条件的。 – 2013-03-12 03:51:48

回答

1

这里是一个SSCCE根据您的代码(Short, Self-Contained, Complete Example):

#include <stdio.h> 
#include <stdlib.h> 
#include <curses.h> 

int main(void) 
{ 
    int ch; 
    char input[100]; 

    initscr(); 
    raw(); 
    keypad(stdscr, TRUE); 
    noecho(); 
    ch = getch(); 
    endwin(); 

    if (ch== KEY_UP) 
     printf("\nUp Arrow\n"); 

    if (ch== KEY_DOWN) 
     printf("\ndown Arrow\n"); 

    fflush(stdout); 

    while(1) 
    { 
     if (fgets(input, sizeof (input), stdin) == NULL) 
     { 
      printf("Early exit\n"); 
      exit(0); 
     } 
     printf("Read: %s", input); 
     fflush(stdout); 
    } 

    printf("Late exit\n"); 
    return 0; 
} 

当我运行它,它正确地检测,如果我使用向上或向下箭头键,后一报告它已经叫endwin()而不是之前。 fflush()调用通常不是必须的,但是在完成curses之后,似乎标准输出完全缓冲而不是行缓冲,这有点令人惊讶。 (我正在测试Mac OS X 10.8.2。)

我使用的另一个技巧是诊断打印,所以我知道发生了什么。我打电话给curses程序,当我运行它时,屏幕被清除;然后我输入一个向上的箭头(在这种情况下),然后sssddd并返回,然后控制-d以指示输入(EOF)的端部,和输出的其余部分是:

$ ./curses 

Up Arrow 
sssddd 
Read: sssddd 
Early exit 
$ 

它是所有除了标准输出上的缓冲之外,其行为与我所预期的相同。在这个程序中没有办法到达Late exit打印声明。

+0

我是一个使用Mac,netbeans,并且我得到了提前退出。 向上箭头 提前退出 成功运行(总时间:1秒) – NoNameY0 2013-03-12 04:39:55

+0

我不知道如何使用NetBeans - 比我做的XCode或者Eclipse了。我没有解释你为什么立即获得“提前退出”。我不认为你使用的终端程序应该是一个因素(但我使用'/ Applications/Utilities/Terminal')。我不认为shell应该是一个因素(但是我使用'/ bin/sh',又名'bash')。如果您在NetBeans中编译并从终端直接运行,会发生什么情况? – 2013-03-12 04:47:01

+0

在bash中也有相同的错误。我只是放弃了。 :( – NoNameY0 2013-03-12 04:53:13

-2

如上所述,输入未定义。另外,fgets用于文件输入流,不用于读取std输入流。 (使用gets代替)

+2

从'man gets':'不要使用gets()。因为事先不知道数据是不可能的,因为get()会读取多少个字符,并且gets()会继续存储超过缓冲区,使用起来非常危险,已经被用来破坏计算机的安全,改用fgets()。“ – 2013-03-12 03:53:50

+1

是的,你说得对。我完全忘了gets()没有强制执行边界。所以,听听上面的人不要使用gets()。 – ByteByter 2013-03-12 07:15:41