2

我一直在尝试getch在另一个项目中工作,但没有成功。所以我已经制作了最基本的程序,我可以使用getch我希望它在主程序中工作的方式。

我研究了对noecho,和的需求cbreak,我也尝试过使用但没有成功。initscrnodelaynewscr()

我遇到的问题是字符不会被打印到屏幕上,直到我点击“输入”,当它们应该在put每个循环时出现在屏幕上时。为什么会这样?此外,光标不会在新行处返回屏幕左侧。例如。

abc  
   def
      ghi

我一直在寻找答案,但又被难住了……

#include <stdio.h>
#include <ncurses.h>

int main()
  {
     initscr();cbreak(); noecho();nodelay(stdscr,0);
    char c ;
    while((c=getch())!=EOF){
    putchar(c);}

    return 0;
  }
4

2 回答 2

7

您没有看到输出,因为您的stdout流是行缓冲的。

您的程序正在使各个字符正常;但输出流正在缓冲它们。

尝试fflush(stdout);或切换stdout到无缓冲模式setbuf(stdout, NULL);

禁用缓冲的问题在于,当输出不是终端时,批量数据处理效率低下。

您可以使其以标准输出为 tty 为条件:

if (isatty(fileno(stdout)))  /* #include <unistd.h> */
  setbuf(stdout, NULL);

要将光标返回到行首,您需要输出一个回车符\r。这是因为 curses 的cbreak模式禁用了ONLCRtty 模式(在输出上,发送 NL 添加 CR 时)。

如果您无条件添加\r,那么当您的输出被重定向时,它将出现在文件中。因此,您再次需要一些isatty技巧。

一个更好的方法可能是学习如何使用tcgetattrtcsetattr函数来精确控制特定的 tty 参数,如果您只想在没有回显的情况下进行一次字符输入,而不是实际开发基于诅咒的交互式程序。

你真的想要一次输入一个字符,还是只是为了禁用回声?禁用回声很容易。调用以使用文件描述符 0 的当前设置tcgetattr填充 a (如果它是 tty)。struct termios翻转一些标志以关闭回显,然后调用tcsetattr以安装更新的结构。当您的程序退出时,请善待并放回原来的程序。完毕。

于 2012-04-21T05:38:16.163 回答
2

是的,ncurses 是获得逐个字符控制的好方法。

是的,你必须调用“initscr()”和“cbreak()”。

建议:

1)将您的代码与此 ncurses “hello world”进行比较:

#include <ncurses.h>

int main()
{   
    initscr();          /* Start curses mode          */
    printw("Hello World !!!");  /* Print Hello World          */
    refresh();          /* Print it on to the real screen */
    getch();            /* Wait for user input */
    endwin();           /* End curses mode        */

    return 0;
}

2) 看看如果你执行“refresh()”和/或删除“noecho()”会发生什么。

3) 本教程有很多有用的信息,可能也会有所帮助:

http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/

于 2012-04-21T05:36:18.363 回答