Enter를 누르지 않고 표준 입력에서 문자를 캡처합니다.
나는 종종 그렇게하지 않기 때문에 내가 어떻게하는지 기억할 수 없다. 그러나 C 또는 C ++에서 줄 바꿈을 기다리지 않고 표준 입력에서 문자를 읽는 가장 좋은 방법은 무엇입니까 (Enter를 누르십시오).
또한 입력 문자를 화면에 에코하지 않는 것이 이상적입니다. 콘솔 화면에 영향을 미치지 않고 키 입력을 캡처하고 싶습니다.
순수한 C ++에서는 이식 가능한 방식으로 불가능합니다. 연결 된 터미널에 너무 많이 의존하기 때문입니다 stdin
(일반적으로 라인 버퍼링 됨). 그러나이를 위해 라이브러리를 사용할 수 있습니다.
conio는 Windows 컴파일러에서 사용 가능합니다. 이
_getch()
기능을 사용하여 Enter 키를 기다리지 않고 문자를 제공하십시오. 나는 빈번한 Windows 개발자는 아니지만, 반 친구들이 그것을 포함<conio.h>
하고 사용하는 것을 보았습니다 .conio.h
Wikipedia를 참조하십시오 . 그것은 나열getch()
Visual C ++에서 사용되지 선언된다.Linux에서 사용할 수있는 저주. Windows에서도 호환되는 curses 구현을 사용할 수 있습니다.
getch()
기능 도 있습니다. (man getch
맨 페이지를 보려고 시도하십시오 ). Wikipedia의 저주 를 참조하십시오 .
크로스 플랫폼 호환성을 목표로하는 경우 curses를 사용하는 것이 좋습니다. 즉, 라인 버퍼링을 해제하는 데 사용할 수있는 기능이 있다고 확신합니다 ( "요리 모드"와 달리 "원시 모드"라고 생각합니다 man stty
.). 내가 실수하지 않으면 저주는 휴대용 방식으로 당신을 위해 그것을 처리 할 것입니다.
Linux (및 기타 유닉스 계열 시스템)에서는 다음과 같은 방법으로 수행 할 수 있습니다.
#include <unistd.h>
#include <termios.h>
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);
}
기본적으로 표준 모드 (및 에코를 억제하려면 에코 모드)를 꺼야합니다.
동일한 문제를 해결하는 동안 다른 포럼에서 이것을 발견했습니다. 내가 찾은 것에서 약간 수정했습니다. 잘 작동합니다. OS X를 실행하고 있으므로 Microsoft를 실행하는 경우 원시 및 요리 모드로 전환하려면 올바른 system () 명령을 찾아야합니다.
#include <iostream>
#include <stdio.h>
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;
}
코니 오
필요한 기능은 다음과 같습니다.
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
#include <conio.h>
if (kbhit() != 0) {
cout << getch() << endl;
}
이 용도는 kbhit()
키보드를 누를 사용되는 경우 확인 getch()
누르고있는 캐릭터를 얻을 수 있습니다.
창문에 있다면 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
솔직히 말하면 이것은 내가 가지고있는 오래된 코드에서 온 것이므로 약간만 사용해야합니다.
멋진 점은 아무 것도 묻지 않고 입력을 읽으므로 문자가 전혀 표시되지 않는다는 것입니다.
Windows를 가정하면 ReadConsoleInput 함수를 살펴보십시오 .
C and C++ take a very abstract view of I/O, and there is no standard way of doing what you want. There are standard ways to get characters from the standard input stream, if there are any to get, and nothing else is defined by either language. Any answer will therefore have to be platform-specific, perhaps depending not only on the operating system but also the software framework.
There's some reasonable guesses here, but there's no way to answer your question without knowing what your target environment is.
The closest thing to portable is to use the ncurses
library to put the terminal into "cbreak mode". The API is gigantic; the routines you'll want most are
initscr
andendwin
cbreak
andnocbreak
getch
Good luck!
I use kbhit() to see if a char is present and then getchar() to read the data. On windows, you can use "conio.h". On linux, you will have to implement your own kbhit().
See code below:
// kbhit
#include <stdio.h>
#include <sys/ioctl.h> // For FIONREAD
#include <termios.h>
#include <stdbool.h>
int kbhit(void) {
static bool initflag = false;
static const int STDIN = 0;
if (!initflag) {
// Use termios to turn off line buffering
struct termios term;
tcgetattr(STDIN, &term);
term.c_lflag &= ~ICANON;
tcsetattr(STDIN, TCSANOW, &term);
setbuf(stdin, NULL);
initflag = true;
}
int nbbytes;
ioctl(STDIN, FIONREAD, &nbbytes); // 0 is STDIN
return nbbytes;
}
// main
#include <unistd.h>
int main(int argc, char** argv) {
char c;
//setbuf(stdout, NULL); // Optional: No buffering.
//setbuf(stdin, NULL); // Optional: No buffering.
printf("Press key");
while (!kbhit()) {
printf(".");
fflush(stdout);
sleep(1);
}
c = getchar();
printf("\nChar received:%c\n", c);
printf("Done.\n");
return 0;
}
The following is a solution extracted from Expert C Programming: Deep Secrets, which is supposed to work on SVr4. It uses stty and ioctl.
#include <sys/filio.h>
int kbhit()
{
int i;
ioctl(0, FIONREAD, &i);
return i; /* return a count of chars available to read */
}
main()
{
int i = 0;
intc='';
system("stty raw -echo");
printf("enter 'q' to quit \n");
for (;c!='q';i++) {
if (kbhit()) {
c=getchar();
printf("\n got %c, on iteration %d",c, i);
}
}
system("stty cooked echo");
}
I always wanted a loop to read my input without pressing return key. this worked for me.
#include<stdio.h>
main()
{
char ch;
system("stty raw");//seting the terminal in raw mode
while(1)
{
ch=getchar();
if(ch=='~'){ //terminate or come out of raw mode on "~" pressed
system("stty cooked");
//while(1);//you may still run the code
exit(0); //or terminate
}
printf("you pressed %c\n ",ch); //write rest code here
}
}
works for me on windows:
#include <conio.h>
char c = _getch();
ncurses provides a nice way to do this! Also this is my very first post (that I can remember), so any comments at all are welcome. I will appreciate useful ones, but all are welcome!
to compile: g++ -std=c++11 -pthread -lncurses .cpp -o
#include <iostream>
#include <ncurses.h>
#include <future>
char get_keyboard_input();
int main(int argc, char *argv[])
{
initscr();
raw();
noecho();
keypad(stdscr,true);
auto f = std::async(std::launch::async, get_keyboard_input);
while (f.wait_for(std::chrono::milliseconds(20)) != std::future_status::ready)
{
// do some work
}
endwin();
std::cout << "returned: " << f.get() << std::endl;
return 0;
}
char get_keyboard_input()
{
char input = '0';
while(input != 'q')
{
input = getch();
}
return input;
}
You can do it portably using SDL (the Simple DirectMedia Library), though I suspect you may not like its behavior. When I tried it, I had to have SDL create a new video window (even though I didn't need it for my program) and have this window "grab" almost all keyboard and mouse input (which was okay for my usage but could be annoying or unworkable in other situations). I suspect it's overkill and not worth it unless complete portability is a must--otherwise try one of the other suggested solutions.
By the way, this will give you key press and release events separately, if you're into that.
'IT' 카테고리의 다른 글
파이썬에서 여러 줄로 된 dict을 형식화하는 올바른 방법은 무엇입니까? (0) | 2020.06.02 |
---|---|
하위 프로세스 Popen과 call의 차이점은 무엇입니까 (어떻게 사용할 수 있습니까)? (0) | 2020.06.02 |
서브 클래스에 대한 포인터에서 delete가 기본 클래스 소멸자를 호출합니까? (0) | 2020.06.02 |
다음 LINQ 문은 어떻게 작동합니까? (0) | 2020.06.02 |
명령 프롬프트-해당 배치 파일이 실행되도록 설정된 경로를 추가하는 방법은 무엇입니까? (0) | 2020.06.01 |