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

2024-11-11 08:27:00
admin
原创
23
摘要:问题描述: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;
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用