当前位置:  开发笔记 > 编程语言 > 正文

从标准输入中捕获字符,无需等待按下输入

如何解决《从标准输入中捕获字符,无需等待按下输入》经验,为你挑选了8个好方法。

我永远不会记得我是怎么做的,因为它对我来说很少见.但是在C或C++中,从标准输入读取字符而不等待换行符的最佳方法是什么(按回车键).

理想情况下,它也不会将输入字符回显到屏幕上.我只想捕捉击键而不影响控制台屏幕.



1> Johannes Sch..:

这在纯C++中是不可能的,因为它过分依赖于可能与stdin连接的终端(它们通常是行缓冲的).但是,你可以使用一个库:

    conio可用于Windows编译器.使用该功能stdin可以在不等待回车键的情况下为您提供角色.我不是常见的Windows开发人员,但我看到我的同学只是包含_getch()并使用它.请参阅维基百科的conio.h.它列出了,在Visual C++中声明已弃用.

    curses可用于linux,兼容的curses实现也可用于Windows.它还有一个conio.h功能.(尝试getch()查看其联机帮助页).请参阅维基百科的Curses.

如果您的目标是跨平台兼容性,我建议您使用curses.也就是说,我确信有一些功能可以用来关闭线缓冲(我相信这叫做"原始模式",而不是"煮熟模式"(查看getch())).如果我没弄错的话,诅咒会以便携的方式为你处理.


请注意,现在,`ncurses`是`curses`的推荐变体.
如果您确实需要一个图书馆,那么他们是怎么做到的?要确定您必须对该库进行编程,那意味着任何人都可以对其进行编程,那么为什么我们不能对我们自己需要的库代码进行编程呢?这也将使得**在纯c ++中不可能移植**

2> 小智..:

在Linux(以及其他类似unix的系统)上,可以通过以下方式完成:

#include 
#include 

char getch() {
        char buf = 0;
        struct termios old = {0};
        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");
        return (buf);
}

基本上你必须关闭规范模式(和回声模式来抑制回声).


可能是因为这段代码是错误的,因为read()是在unistd.h中定义的POSIX系统调用.stdio.h可能巧合地包含它,但实际上你根本不需要stdio.h; 用unistd.h替换它应该是好的.
有没有简单的方法将其扩展到不阻止?
@FalconMomot在我的NetBeans IDE 8.1(在Kali Linux中)中说:“错误:编译时未在此范围内声明'perror',但在包含`stdio.h`和`unistd.h`时可以正常工作。

3> cwhiii..:

我在寻找解决同样问题的同时在另一个论坛上找到了这个.我从我发现的东西中修改了一下.它很棒.我正在运行OS X,所以如果你正在运行Microsoft,你需要找到正确的system()命令来切换到raw和cooked模式.

#include  
#include   
using namespace std;  

int main() { 
  // Output prompt 
  cout << "Press any key to continue..." << endl; 

  // Set terminal to raw mode 
  system("stty raw"); 

  // Wait for single character 
  char input = getchar(); 

  // Echo input:
  cout << "--" << input << "--";

  // Reset terminal to normal "cooked" mode 
  system("stty cooked"); 

  // And we're out of here 
  return 0; 
}


虽然这是有效的,但对于它的价值而言,在我看来,对系统进行外壳很少是"最好"的方法.stty程序是用C语言编写的,所以你可以包含并调用stty使用的相同代码,而不依赖于外部程序/ fork/whatnot.

4> 小智..:

CONIO.H

你需要的功能是:

int getch();
Prototype
    int _getch(void); 
Description
    _getch obtains a character  from stdin. Input is unbuffered, and this
    routine  will  return as  soon as  a character is  available  without 
    waiting for a carriage return. The character is not echoed to stdout.
    _getch bypasses the normal buffering done by getchar and getc. ungetc 
    cannot be used with _getch. 
Synonym
    Function: getch 


int kbhit();
Description
    Checks if a keyboard key has been pressed but not yet read. 
Return Value
    Returns a non-zero value if a key was pressed. Otherwise, returns 0.

libconio http://sourceforge.net/projects/libconio

要么

conio.h的Linux c ++实现 http://sourceforge.net/projects/linux-conioh



5> hasen..:

如果您在Windows上,可以使用PeekConsoleInput来检测是否有任何输入,

HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
DWORD events;
INPUT_RECORD buffer;
PeekConsoleInput( handle, &buffer, 1, &events );

然后使用ReadConsoleInput"消耗"输入字符..

PeekConsoleInput(handle, &buffer, 1, &events);
if(events > 0)
{
    ReadConsoleInput(handle, &buffer, 1, &events);  
    return buffer.Event.KeyEvent.wVirtualKeyCode;
}
else return 0

说实话,这是来自我的一些旧代码,所以你必须弄清楚它.

但很酷的是,它在没有提示任何内容的情况下读取输入,因此根本不显示字符.



6> Joseph Dykst..:
#include 

if (kbhit() != 0) {
    cout << getch() << endl;
}

这用于kbhit()检查键盘是否被按下并用于getch()获取正在按下的字符.


[CONIO.H](http://en.wikipedia.org/wiki/Conio.h)?"conio.h是旧的MS-DOS编译器中用于创建文本用户界面的C头文件." 似乎有些过时了.

7> 小智..:

假设Windows,请查看ReadConsoleInput函数.



8> David Thornl..:

C和C++采用非常抽象的I/O视图,没有标准的方法来做你想做的事情.有标准方法可以从标准输入流中获取字符,如果有任何要获取的字符,则任何一种语言都没有定义任何其他内容.因此,任何答案都必须是特定于平台的,可能不仅取决于操作系统,还取决于软件框架.

这里有一些合理的猜测,但是如果不知道你的目标环境是什么,就无法回答你的问题.

推荐阅读
360691894_8a5c48
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有