在Linux中,与getch()和getche()等效的函数是什么?

86

我找不到Linux中与conio.h等价的头文件。

在Linux中是否有getch()getche()函数的选项?

我想制作一个基于switch case的菜单,用户只需按一个键即可选择选项并继续处理。 我不想让用户在按下选择后再按ENTER键。

6个回答

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

static struct termios old, current;

/* Initialize new terminal i/o settings */
void initTermios(int echo) 
{
  tcgetattr(0, &old); /* grab old terminal i/o settings */
  current = old; /* make new settings same as old settings */
  current.c_lflag &= ~ICANON; /* disable buffered i/o */
  if (echo) {
      current.c_lflag |= ECHO; /* set echo mode */
  } else {
      current.c_lflag &= ~ECHO; /* set no echo mode */
  }
  tcsetattr(0, TCSANOW, &current); /* use these new terminal i/o settings now */
}

/* Restore old terminal i/o settings */
void resetTermios(void) 
{
  tcsetattr(0, TCSANOW, &old);
}

/* Read 1 character - echo defines echo mode */
char getch_(int echo) 
{
  char ch;
  initTermios(echo);
  ch = getchar();
  resetTermios();
  return ch;
}

/* Read 1 character without echo */
char getch(void) 
{
  return getch_(0);
}

/* Read 1 character with echo */
char getche(void) 
{
  return getch_(1);
}

/* Let's test it out */
int main(void) {
  char c;
  printf("(getche example) please type a letter: ");
  c = getche();
  printf("\nYou typed: %c\n", c);
  printf("(getch example) please type a letter...");
  c = getch();
  printf("\nYou typed: %c\n", c);
  return 0;
}

输出:

(getche example) please type a letter: g
You typed: g
(getch example) please type a letter...
You typed: g

5
谢谢,它有效了,但我不得不用其他东西替换new,因为我猜它是一个关键字。 - Mihai Vilcu
1
在Windows上,您可以在Windows API中包含_getch,在<conio.h>中。 - Paul Stelian
2
@MihaiVilcu new 是 C++ 中的关键字,但不是 C 中的。 - Paul Stelian
1
@PaulStelian 我当时使用的是mingw-gcc,如果我没记错的话,它没有conio或termios。 - cipher
2
这个示例中有一个错误:当echo为true时,new.c_lflag &= ECHO是不正确的,它将清除除ECHO之外的所有位,应该是new.c_lflag |= ECHO - RedSoft
显示剩余4条评论

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

char getch(void)
{
    char buf = 0;
    struct termios old = {0};
    fflush(stdout);
    if(tcgetattr(0, &old) < 0)
        perror("tcsetattr()");
    old.c_lflag &= ~ICANON;
    old.c_lflag &= ~ECHO;
    old.c_cc[VMIN] = 1;
    old.c_cc[VTIME] = 0;
    if(tcsetattr(0, TCSANOW, &old) < 0)
        perror("tcsetattr ICANON");
    if(read(0, &buf, 1) < 0)
        perror("read()");
    old.c_lflag |= ICANON;
    old.c_lflag |= ECHO;
    if(tcsetattr(0, TCSADRAIN, &old) < 0)
        perror("tcsetattr ~ICANON");
    printf("%c\n", buf);
    return buf;
 }

如果您不想显示字符,则删除最后一个printf


2
@mr-32 这是 Linux 中与 Visual Studio for Windows 使用的 getch() 函数完全相同的函数,只是在该函数的最后一行省略了 printf()。 - mf_
我希望不是这样,因为它有一个错误。它假设在重置到旧状态时,ICANON和ECHO已经被设置。 - pjcard

7

我建议您使用curses.h或ncurses.h,它们实现了包括getch()在内的键盘管理例程。您有多种选项可以更改getch()的行为(例如等待按键或不等待)。


4

在ncurses库中有一个getch()函数。您可以通过安装ncurses-dev包来获取它。


2
有一种情况,我不想安装新的东西,还有其他的选择吗? - Jeegar Patel

-1

-1

你可以像其他答案所提到的那样,在 Linux 中使用 curses.h 库。

你可以通过以下方式在 Ubuntu 中安装:

sudo apt-get update

sudo apt-get install ncurses-dev

我从这里取得了安装部分的内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接