为什么 getch() 在按任何键之前就返回?

2024-11-11 08:27:00
admin
原创
157
摘要:问题描述:int main(int argc, char *argv[], char *env[]) { printf("Press any key to exit. "); getch(); return 0; } 根据手册页,getch应该等到按下任意键...但...

问题描述:

int main(int argc, char *argv[], char *env[])
{
    printf("Press any key to exit.
");
    getch();
    return 0;
}

根据手册页,

getch应该等到按下任意键

...但实际上它在按任何键之前直接返回。(返回的值是-1)。

为什么?


更新

我在 Linux 上。Press any key to exit.如果不使用,我该如何实现getch()

getchar()按下Enter后才会返回,这不是我想要的。


解决方案 1:

在 Linux 上,getch()可能是curses函数,它与同名的 Windows 特定函数有很大不同。 curses( ncurses) 可能对于您想要做的事情来说有点小题大做。

最简单的方法是等到用户按下Enter,您可以这样做:

int c;
printf("Press <enter> to quit: ");
fflush(stdout);
while ((c = getchar()) != '
' && c != EOF) {
    /* nothing */
}

如果您确实希望用户能够按任意键,而不仅仅是Enter,您可以执行以下操作:

system("stty cbreak -echo");
getchar();
system("stty cooked echo");

第二个stty目的是将 tty 恢复到合理的设置(它应该真的将它们恢复到原来的状态,但保存和恢复状态有点复杂)。可能有更简洁的方法来实现这一点(使用程序stty本身使用的任何库函数)。

编辑:不等待就读取单个字符Enter是一个常见问题。事实上,这是comp.lang.c FAQ中的问题 19.1 。

编辑 2:我最近没有用过 curses,但我只是玩了一下。除非你先调用-- 并清除屏幕,否则它似乎getch()不会起作用。curses 旨在用于需要完全控制显示的应用程序(如文本编辑器)。可能有一种方法可以在不控制屏幕的情况下使用,但我还没有找到。initscr()`initscr()`getch()

实际上,这个system("stty ...")临时解决办法可能才是最好的办法。

EDIT3:termios另一个答案中的解决方案可能是最好的(更system("stty ...")简单,但调用外部程序感觉有点小题大做。

至于 OP 的评论“我不敢相信Press any key to exit.用 c 来实现这么麻烦”,是的,这确实看起来很奇怪——但进一步思考后发现这是有充分理由的。

看一下典型的 Unix 或 Linux 系统上安装的程序。我想你会发现它们中很少有程序需要这种输入(等待一次按键)。

许多程序使用命令行参数和从文件或 读取的数据stdin。用户输入的任何内容都是输入数据,而不是命令或对提示的响应。

有些程序确实会要求确认某些操作(安装程序喜欢apt-getcpan经常这样做)——但它们通常会读取一行输入并检查第一个字符。或者,对于某些激烈的操作,它们可能会要求您输入整个单词“yes”,然后输入Enter(您不会想因为不小心按到某个键而重新格式化硬盘)。

当然,许多程序(文本编辑器、文件查看器)读取单字符无回显输入,但此类程序往往基于 curses;它们控制整个终端窗口。

最后,许多程序都有 GUI 界面(Web 浏览器等);它们甚至可能不从标准输入读取。

大多数生产 Unix 程序不使用或不需要Press any key to exit提示。它们只是默默地完成工作,然后终止,以便您可以做下一件事。这种需求主要存在于相对基本的程序中,例如家庭作业。并不是说家庭作业有什么问题,而是整个系统主要不是为支持这种用法而设计的。

解决方案 2:

这是一个简单的例子

#include <curses.h>

int main(){
    initscr();
    cbreak();
    noecho();
    printw("Press any key to continue.");
    refresh();
    getch();
    endwin();
    return 0;
}

但似乎没有办法在不清除屏幕的情况下使用 ncurses。也许是 Overkill 的污点?!

编辑

这是我发现的另一种方法。这种方法不使用诅咒,也不清除屏幕。

#include <stdio.h>
#include <termios.h>
#include <unistd.h>

int main() {
    struct termios old,new;

    tcgetattr(fileno(stdin),&old);
    tcgetattr(fileno(stdin),&new);
    cfmakeraw(&new);
    tcsetattr(fileno(stdin),TCSANOW,&new);
    fputs("Press any key to continue.",stdout);
    fflush(NULL);
    fgetc(stdin);
    tcsetattr(fileno(stdin),TCSANOW,&old);

    return 0;
}

手册页说 cfmakeraw() 可能不是完全可移植的。但它只是设置一堆标志的简写:

Raw mode
    cfmakeraw() sets the terminal to something like the "raw" mode of the old  Version  7  terminal
    driver:  input  is  available character by character, echoing is disabled, and all special pro-
    cessing of terminal input and output characters is disabled.  The terminal attributes  are  set
    as follows:

       termios_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
                       | INLCR | IGNCR | ICRNL | IXON);
       termios_p->c_oflag &= ~OPOST;
       termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
       termios_p->c_cflag &= ~(CSIZE | PARENB);
       termios_p->c_cflag |= CS8;
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1142  
  IPD(Integrated Product Development,集成产品开发)流程是一种广泛应用于高科技和制造业的产品开发方法论。它通过跨职能团队的紧密协作,将产品开发周期缩短,同时提高产品质量和市场成功率。在IPD流程中,CDCP(Concept Decision Checkpoint,概念决策检查点)是一个关...
IPD培训课程   96  
  研发IPD(集成产品开发)流程作为一种系统化的产品开发方法,已经在许多行业中得到广泛应用。它不仅能够提升产品开发的效率和质量,还能够通过优化流程和资源分配,显著提高客户满意度。客户满意度是企业长期成功的关键因素之一,而IPD流程通过其独特的结构和机制,能够确保产品从概念到市场交付的每个环节都围绕客户需求展开。本文将深入...
IPD流程   87  
  IPD(Integrated Product Development,集成产品开发)流程是一种以跨职能团队协作为核心的产品开发方法,旨在通过优化资源分配、提高沟通效率以及减少返工,从而缩短项目周期并提升产品质量。随着企业对产品上市速度的要求越来越高,IPD流程的应用价值愈发凸显。通过整合产品开发过程中的各个环节,IPD...
IPD项目管理咨询   95  
  跨部门沟通是企业运营中不可或缺的一环,尤其在复杂的产品开发过程中,不同部门之间的协作效率直接影响项目的成败。集成产品开发(IPD)作为一种系统化的项目管理方法,旨在通过优化流程和增强团队协作来提升产品开发的效率和质量。然而,跨部门沟通的复杂性往往成为IPD实施中的一大挑战。部门之间的目标差异、信息不对称以及沟通渠道不畅...
IPD是什么意思   92  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用