Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
getch和putchar在没有返回的情况下不工作_C_Ncurses_Getch_Putchar - Fatal编程技术网

getch和putchar在没有返回的情况下不工作

getch和putchar在没有返回的情况下不工作,c,ncurses,getch,putchar,C,Ncurses,Getch,Putchar,我一直试图让getch在另一个程序中工作,但没有成功。因此,我用getch在主程序中运行的方式编写了最基本的程序 我已经研究过对noecho、cbreak、initscr和nodelay的需求,我也尝试过使用newscr(),但没有成功 我遇到的问题是,在我点击“回车”键之前,字符不会被打印到屏幕上,而每次循环时,字符都应该被放到屏幕上。为什么会这样?此外,光标不会返回到屏幕左侧的新行。例如 abc def ghi 我一直在寻找答案,但又被难住了 #include <

我一直试图让
getch
在另一个程序中工作,但没有成功。因此,我用
getch
在主程序中运行的方式编写了最基本的程序

我已经研究过对
noecho
cbreak
initscr
nodelay
的需求,我也尝试过使用
newscr()
,但没有成功

我遇到的问题是,在我点击“回车”键之前,字符不会被打印到屏幕上,而每次循环时,字符都应该被
放到屏幕上。为什么会这样?此外,光标不会返回到屏幕左侧的新行。例如

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;
  }
#包括
#包括
int main()
{
initscr();cbreak();noecho();nodelay(stdscr,0);
字符c;
而((c=getch())!=EOF){
putchar(c);}
返回0;
}

是的,ncurses是获取逐字符控制的好方法

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

建议:

1) 将您的代码与本课程“hello world”进行比较:

#包括
int main()
{   
initscr();/*开始诅咒模式*/
printw(“Hello World!!!”;/*打印Hello World*/
刷新();/*将其打印到真实屏幕上*/
getch();/*等待用户输入*/
endwin();/*结束诅咒模式*/
返回0;
}
2) 查看如果执行“刷新()”和/或删除“noecho()”会发生什么

3) 本教程提供了很多有用的信息:


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

您的程序正在正确处理各个字符;但是输出流正在缓冲它们

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

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

您可以将其设置为标准输出为tty的条件:

if (isatty(fileno(stdout)))  /* #include <unistd.h> */
  setbuf(stdout, NULL);
if(isatty(fileno(stdout))/*#包括*/
setbuf(标准输出,空);
要将光标返回到行首,您需要输出回车符
\r
。这是因为curses'cbreak
模式禁用了
ONLCR
tty模式(在输出时,发送NL add CR时)

如果无条件添加
\r
,则在重定向输出时,它将显示在文件中。所以你需要一些
isatty
hack

更好的方法可能是学习如何使用
tcgetattr
tcsetattr
函数精确控制特定的tty参数,如果您只想一次输入一个字符而不需要回显,而不是实际开发基于诅咒的交互式程序


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

如果您想知道我为什么这样做,我会尝试从标准输入获取输入,只打印到不是空的标准输出行。如果您只是想实现文本过滤器,那么通过诅咒引入终端控制是一个非常糟糕的主意。一次输入一个字符与筛选空行无关。若要将非空行从stdin复制到stdout,请尝试
grep'。
。我可以向你保证,它不使用ncurses。@Kaz;我已经在重定向的stdin文件中成功地使用了一次字符过滤,但是当仅在stdin中使用它时,终端会回显我不想要的stdin。因此,为什么我要尝试通过by进行终端控制,您应该将
getch()
读入
int
,而不是
char
。谢谢书签,很明显我不明白什么是窗户。Hi-Kaz是对的。如果您想要文本模式应用程序的终端控制,Ncurses是一个不错的选择。如果您想要一个简单的过滤器来去除空行(正如您随后解释的),只需使用“sed”或“grep”。例如:“
cat myfile | grep.”
我会使用cat…但这是家庭作业,因此需要制作一个过滤器。但它不能解决缺少回车符的问题。我更新了更多答案。谢谢,我会查看它们,它可能比我现在的方式要简单得多。p.s.
如果((c='\n'))putchar('\r'))}
有效,但我知道的代码非常糟糕。
tcsetattr
经过多次关于如何设置旗帜和欢呼声的讨论,非常感谢您的支持。
if (isatty(fileno(stdout)))  /* #include <unistd.h> */
  setbuf(stdout, NULL);