有没有一种方法可以在不按回车键的情况下获得用户输入
Is there a way to get user input without pressing the enter key?
我正在编写一个控制台游戏(pac-man),我想知道如果用户不按回车键,我该如何获得用户输入。我在互联网上浏览了一下,发现了一些关于_getch()
的东西,但它显然不再是最新的,也没有已知的头文件来声明它,除非有人自己构建它,我不能这样做,因为我对C++还很陌生。那么,我该如何构建一个能够做到这一点的代码呢?感谢
这对我有效(我在linux上):
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
int main()
{
struct termios old_tio, new_tio;
unsigned char c;
/* get the terminal settings for stdin */
tcgetattr(STDIN_FILENO,&old_tio);
/* we want to keep the old setting to restore them a the end */
new_tio=old_tio;
/* disable canonical mode (buffered i/o) and local echo */
new_tio.c_lflag &=(~ICANON & ~ECHO);
/* set the new settings immediately */
tcsetattr(STDIN_FILENO,TCSANOW,&new_tio);
do {
c=getchar();
printf("%d ",c);
} while(c!='q');
/* restore the former settings */
tcsetattr(STDIN_FILENO,TCSANOW,&old_tio);
return 0;
}
它使控制台没有缓冲区。
参考:http://shtrom.ssji.net/skb/getc.html
您可以使用conio.h库和函数_getch()以实时方式获取输入,还可以为多个输入设置循环。
#include<conio.h>
#include<iostream>
using namespace std;
int main()
{
char n = 'a'; //Just to initialize it.
while(n != 'e') // Will exit if you press e.
{
n = _getch();
}
}
允许本地文本编辑的Windows解决方案
#include <Windows.h>
#include <conio.h>
enum key_code
{
KEY_QUIT = 3,
KEY_BACKSPACE = 8,
KEY_TAB = 9,
KEY_RETURN = 13,
KEY_ESCAPE = 27,
KEY_SPACE = ' ',
KEY_EXCLAMATION_POINT = '!',
KEY_QUOTATION = '"',
KEY_HASHTAG = '#',
KEY_DOLLAR = '$',
KEY_MODULUS = '%',
KEY_AMPERSAND = '&',
KEY_APOSTROPHE = ''',
KEY_LEFT_PAREN = '(',
KEY_RIGHT_PAREN = ')',
KEY_ASTERICK = '*',
KEY_PLUS = '+',
KEY_COMMA = ',',
KEY_MINUS = '-',
KEY_PERIOD = '.',
KEY_FORWARD_SLASH = '/',
KEY_0 = '0',
KEY_1 = '1',
KEY_2 = '2',
KEY_3 = '3',
KEY_4 = '4',
KEY_5 = '5',
KEY_6 = '6',
KEY_7 = '7',
KEY_8 = '8',
KEY_9 = '9',
KEY_COLON = ':',
KEY_SEMICOLON = ';',
KEY_LESS_THAN = '<',
KEY_EQUALS = '=',
KEY_GREATER_THAN = '>',
KEY_QUESTION = '?',
KEY_AT = '@',
KEY_A = 'A',
KEY_B = 'B',
KEY_C = 'C',
KEY_D = 'D',
KEY_E = 'E',
KEY_F = 'F',
KEY_G = 'G',
KEY_H = 'H',
KEY_I = 'I',
KEY_J = 'J',
KEY_K = 'K',
KEY_L = 'L',
KEY_M = 'M',
KEY_N = 'N',
KEY_O = 'O',
KEY_P = 'P',
KEY_Q = 'Q',
KEY_R = 'R',
KEY_S = 'S',
KEY_T = 'T',
KEY_U = 'U',
KEY_V = 'V',
KEY_W = 'W',
KEY_X = 'X',
KEY_Y = 'Y',
KEY_Z = 'Z',
KEY_OPENING_SQR_BRACE = '[',
KEY_BACKSLASH = '',
KEY_CLOSING_SQR_BRACE = ']',
KEY_EXP = '^',
KEY_UNDERSCORE = '_',
KEY_BACKTICK = '`',
KEY_a = 'a',
KEY_b = 'b',
KEY_c = 'c',
KEY_d = 'd',
KEY_e = 'e',
KEY_f = 'f',
KEY_g = 'g',
KEY_h = 'h',
KEY_i = 'i',
KEY_j = 'j',
KEY_k = 'k',
KEY_l = 'l',
KEY_m = 'm',
KEY_n = 'n',
KEY_o = 'o',
KEY_p = 'p',
KEY_q = 'q',
KEY_r = 'r',
KEY_s = 's',
KEY_t = 't',
KEY_u = 'u',
KEY_v = 'v',
KEY_w = 'w',
KEY_x = 'x',
KEY_y = 'y',
KEY_z = 'z',
KEY_OPENING_CURLY_BRACE = '{',
KEY_LINE = '|',
KEY_CLOSING_CURLY_BRACE = '}',
KEY_TILDA = '~',
KEY_UP_ARROW,
KEY_DOWN_ARROW,
KEY_LEFT_ARROW,
KEY_RIGHT_ARROW,
KEY_DELETE,
KEY_END,
KEY_HOME,
};
struct handle
{
HANDLE console;
DWORD old_mode;
handle() : console{GetStdHandle(STD_OUTPUT_HANDLE)}
{
GetConsoleMode(console, &old_mode);
SetConsoleMode(console, old_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
}
handle(const handle&) = delete;
handle& operator=(const handle&) = delete;
COORD get_cursor_pos() const
{
CONSOLE_SCREEN_BUFFER_INFO screen{};
GetConsoleScreenBufferInfo(console, &screen);
return screen.dwCursorPosition;
}
void set_pos(COORD pos) const
{
SetConsoleCursorPosition(console, pos);
}
void write(const WCHAR* sequence) const
{
DWORD written = 0;
WriteConsoleW(console, sequence, (DWORD)wcslen(sequence), &written, nullptr);
}
void clear_screen() const
{
write(L"x1b[2J");
set_pos({0, 0});
}
~handle()
{
SetConsoleMode(console, old_mode);
}
};
key_code input()
{
int c = _getch();
// if it is a special key and there is another key to be handled
if (c == 224 && _kbhit())
{
c = _getch();
switch (c)
{
case 75:
return KEY_LEFT_ARROW;
case 77:
return KEY_RIGHT_ARROW;
case 72:
return KEY_UP_ARROW;
case 80:
return KEY_DOWN_ARROW;
case 83:
return KEY_DELETE;
case 79:
return KEY_END;
case 71:
return KEY_HOME;
}
}
return static_cast<key_code>(c);
}
struct handler
{
std::wstring text;
handle console;
// holds initial cursor position
COORD cursor_init;
// holds position that the console cursor is for editing
size_t cursor;
bool finished;
handler() : text{}, console{}, cursor{}, finished{true}
{
}
void run()
{
if (finished)
{
text.clear();
cursor_init = console.get_cursor_pos();
cursor = 0;
finished = false;
}
key_code code;
// show cursor
console.write(L"x1b[?25h");
console.set_pos({static_cast<short>(cursor_init.X + cursor), cursor_init.Y});
code = input();
switch (code)
{
case KEY_BACKSPACE:
if (cursor > 0)
{
text.erase(text.begin() + cursor - 1);
--cursor;
}
break;
case KEY_DELETE:
if (cursor < text.size())
text.erase(text.begin() + cursor);
break;
case KEY_LEFT_ARROW:
if (cursor > 0)
--cursor;
break;
case KEY_RIGHT_ARROW:
if (cursor < text.size())
++cursor;
break;
case KEY_HOME:
cursor = 0;
break;
case KEY_END:
cursor = text.size();
break;
case KEY_RETURN:
case KEY_QUIT:
finished = true;
case KEY_UP_ARROW:
case KEY_DOWN_ARROW:
case KEY_ESCAPE:
return;
default:
text.insert(text.begin() + cursor, static_cast<char>(code));
++cursor;
}
// move cursor to beginning of line
console.set_pos(cursor_init);
// clear line
console.write(L"x1b[0K");
console.write(text.data());
console.set_pos({static_cast<short>(cursor_init.X + cursor), cursor_init.Y});
// hide cursor
console.write(L"x1b[?25l");
}
};
// get_input returns true if input is finished (newline is entered)
bool get_input(std::wstring& str)
{
static handler h;
h.run();
str = h.text;
return h.finished;
}
相关文章:
- 在没有太多条件句的情况下,我如何避免被零除
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 在未初始化映射的情况下,将值插入到映射的映射中
- 是默认情况下分配给char数组常量的值
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 如何在不产生任何垃圾的情况下获得C中的像素
- 在已经使用Git的情况下减少编译时间
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 如何在没有信号的情况下从C++执行QML插槽
- 如何在不知道向量大小的情况下输入向量内部的向量?
- 为什么在某些情况下不写入此文件?
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 在没有Xcode的情况下在Mac捆绑包中嵌入框架
- UE4-如何在给定4个屏幕坐标的情况下缩放纹理或材质
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 在C++中如何在没有pow的情况下进行基础计算
- 松弛原子与无同步情况下的记忆连贯性
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 我是c ++的新手,你能解释一下在这种情况下的指针吗
- 在不使用空格或回车的情况下输入两个数据