getchar ()로 Enter 키를 누르지 않는 방법
다음 코드에서 :
#include <stdio.h>
int main(void) {
int c;
while ((c=getchar())!= EOF)
putchar(c);
return 0;
}
으로 Enter입력 한 모든 글자를 인쇄 하려면을 눌러야 하는데이 getchar
작업은하고 싶지 않습니다.하고 싶은 것은를 누르지 않고 소개 한 글자를 즉시 반복해서 보는 것 Enter입니다. 예를 들어, 문자 'a'를 누르면 옆에 다른 'a'가 표시됩니다.
aabbccddeeff.....
하지만 'a'를 눌러도 아무 일도 일어나지 않으면 다른 글자를 쓸 수 있고 다음을 누를 때만 사본이 나타납니다 Enter.
abcdef
abcdef
어떻게 할 수 있습니까?
cc -o example example.c
컴파일을 위해 Ubuntu 에서 명령을 사용하고 있습니다.
Linux 시스템에서는 stty
명령을 사용하여 터미널 동작을 수정할 수 있습니다 . 기본적으로 터미널 Enter은를 누를 때까지 모든 정보를 버퍼링 하고 C 프로그램으로 보내기도합니다.
프로그램 자체에서 동작을 변경하는 빠르고 더럽고 특별히 이식 할 수없는 예제 :
#include<stdio.h>
int main(void){
int c;
/* use system call to make terminal send all keystrokes directly to stdin */
system ("/bin/stty raw");
while((c=getchar())!= '.') {
/* type a period to break out of the loop, since CTRL-D won't work raw */
putchar(c);
}
/* use system call to set terminal behaviour to more normal behaviour */
system ("/bin/stty cooked");
return 0;
}
이것은 stty cooked
원래 터미널 설정이 무엇인지 확인하는 것이 아니라 프로그램이 종료 될 때 원하는 동작 이라고 가정하기 때문에 실제로 최적이 아닙니다 . 또한 모든 특수 처리가 원시 모드에서 건너 뛰기 때문에 많은 키 시퀀스 (예 : CTRL-C 또는 CTRL-D )가 프로그램에서 명시 적으로 처리하지 않으면 예상대로 작동하지 않습니다.
man stty
정확히 원하는 것에 따라 터미널 동작을 더 많이 제어 할 수 있습니다 .
이것은 OS에 따라 다르며 UNIX와 같은 환경에있는 경우 ICANON 플래그가 기본적으로 활성화되어 있으므로 입력은 다음 '\n'
또는 EOF
. 표준 모드를 비활성화하면 즉시 문자를 얻을 수 있습니다. 이것은 다른 플랫폼에서도 가능하지만 직접적인 크로스 플랫폼 솔루션은 없습니다.
편집 : 나는 당신이 우분투를 사용하도록 지정했음을 알았습니다. 어제 비슷한 내용을 게시했지만 이로 인해 터미널의 많은 기본 동작이 비활성화됩니다.
#include<stdio.h>
#include <termios.h> //termios, TCSANOW, ECHO, ICANON
#include <unistd.h> //STDIN_FILENO
int main(void){
int c;
static struct termios oldt, newt;
/*tcgetattr gets the parameters of the current terminal
STDIN_FILENO will tell tcgetattr that it should write the settings
of stdin to oldt*/
tcgetattr( STDIN_FILENO, &oldt);
/*now the settings will be copied*/
newt = oldt;
/*ICANON normally takes care that one line at a time will be processed
that means it will return if it sees a "\n" or an EOF or an EOL*/
newt.c_lflag &= ~(ICANON);
/*Those new settings will be set to STDIN
TCSANOW tells tcsetattr to change attributes immediately. */
tcsetattr( STDIN_FILENO, TCSANOW, &newt);
/*This is your part:
I choose 'e' to end input. Notice that EOF is also turned off
in the non-canonical mode*/
while((c=getchar())!= 'e')
putchar(c);
/*restore the old settings*/
tcsetattr( STDIN_FILENO, TCSANOW, &oldt);
return 0;
}
모든 캐릭터가 두 번 나타납니다. 입력이 즉시 터미널로 다시 에코되고 프로그램이 다시 입력하기 때문 putchar()
입니다. 출력에서 입력을 연결 해제하려면 ECHO 플래그도 설정해야합니다. 적절한 줄을 다음과 같이 변경하면됩니다.
newt.c_lflag &= ~(ICANON | ECHO);
getchar ()는 많은 플랫폼에서 Enter 키를 눌러 입력해야하는 표준 함수입니다. 플랫폼은 해당 키를 누를 때까지 입력을 버퍼링하기 때문입니다. 많은 컴파일러 / 플랫폼은 ENTER를 신경 쓰지 않는 비표준 getch ()를 지원합니다 (플랫폼 버퍼링을 우회하고 ENTER를 다른 키처럼 취급합니다).
I / O는 운영 체제 기능입니다. 대부분의 경우 운영 체제는 Enter 키를 누를 때까지 입력 한 문자를 프로그램에 전달하지 않습니다. 이를 통해 사용자는 입력을 프로그램으로 보내기 전에 백 스페이스 및 재 입력과 같은 입력을 수정할 수 있습니다. 대부분의 경우 이것은 잘 작동하고 사용자에게 일관된 인터페이스를 제공하며 프로그램이이를 처리하지 않아도됩니다. 어떤 경우에는 프로그램이 키를 누를 때 키에서 문자를 가져 오는 것이 바람직합니다.
C 라이브러리 자체는 파일을 처리하며 데이터가 입력 파일에 들어가는 방식에는 관심이 없습니다. 따라서 언어 자체에서 키를 누를 때 얻을 수있는 방법은 없습니다. 대신 이것은 플랫폼에 따라 다릅니다. OS 나 컴파일러를 지정하지 않으 셨기 때문에 찾아 드릴 수 없습니다.
또한 표준 출력은 일반적으로 효율성을 위해 버퍼링됩니다. 이것은 C 라이브러리에 의해 수행되므로 fflush(stdout);
각 문자가 작성된 후에 C 솔루션이 있습니다. 그 후 문자가 즉시 표시되는지 여부는 운영 체제에 달려 있지만 익숙한 모든 OS가 즉시 출력을 표시하므로 일반적으로 문제가되지 않습니다.
Unix 파생물 (Ubuntu)에서 작업하고 있기 때문에 여기에 한 가지 방법이 있습니다. 권장되지는 않지만 작동합니다 (명령을 정확하게 입력 할 수있는 한).
echo "stty -g $(stty -g)" > restore-sanity
stty cbreak
./your_program
지루할 때 프로그램을 중지하려면 인터럽트를 사용하십시오.
sh restore-sanity
- 'echo'줄은 현재 터미널 설정을 복원 할 쉘 스크립트로 저장합니다.
- The 'stty' line turns off most of the special processing (so Control-D has no effect, for example) and sends characters to the program as soon as they are available. It means you cannot edit your typing any more.
- The 'sh' line reinstates your original terminal settings.
You can economize if 'stty sane' restores your settings sufficiently accurately for your purposes. The format of '-g' is not portable across versions of 'stty' (so what is generated on Solaris 10 won't work on Linux, or vice versa), but the concept works everywhere. The 'stty sane' option is not universally available, AFAIK (but is on Linux).
I like Lucas answer, but I would like to elaborate it a bit. There is a built-in function in termios.h
named cfmakeraw()
which man describes as:
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 processing of
terminal input and output characters is disabled. [...]
This basically does the same as what Lucas suggested and more, you can see the exact flags it sets in the man pages: termios(3).
Use case
int c = 0;
static struct termios oldTermios, newTermios;
tcgetattr(STDIN_FILENO, &oldTermios);
newTermios = oldTermios;
cfmakeraw(&newTermios);
tcsetattr(STDIN_FILENO, TCSANOW, &newTermios);
c = getchar();
tcsetattr(STDIN_FILENO, TCSANOW, &oldTermios);
switch (c) {
case 113: // q
printf("\n\n");
exit(0);
break;
case 105: // i
printf("insert\n");
break;
default:
break;
You could include the 'ncurses' library, and use getch()
instead of getchar()
.
yes you can do this on windows too, here's the code below, using the conio.h library
#include <iostream> //basic input/output
#include <conio.h> //provides non standard getch() function
using namespace std;
int main()
{
cout << "Password: ";
string pass;
while(true)
{
char ch = getch();
if(ch=='\r'){ //when a carriage return is found [enter] key
cout << endl << "Your password is: " << pass <<endl;
break;
}
pass+=ch;
cout << "*";
}
getch();
return 0;
}
I've had this problem/question come up in an assignment that I'm currently working on. It also depends on which input you are grabbing from. I am using
/dev/tty
to get input while the program is running, so that needs to be the filestream associated with the command.
On the ubuntu machine I have to test/target, it required more than just
system( "stty -raw" );
or
system( "stty -icanon" );
I had to add the --file flag, as well as path to the command, like so:
system( "/bin/stty --file=/dev/tty -icanon" );
Everything is copacetic now.
By default, the C library buffers the output until it sees a return. To print out the results immediately, use fflush
:
while((c=getchar())!= EOF)
{
putchar(c);
fflush(stdout);
}
참고URL : https://stackoverflow.com/questions/1798511/how-to-avoid-pressing-enter-with-getchar
'program tip' 카테고리의 다른 글
PHP로 계산 된 CRAP 인덱스를 읽고 개선하는 방법 (0) | 2020.11.07 |
---|---|
"공유 객체를 만들 때`.rodata.str1.8 '에 대한 재배치 R_X86_64_32는 사용할 수 없습니다."로 컴파일 실패 (0) | 2020.11.07 |
자바 스크립트 하위 문자열 (0) | 2020.11.07 |
jQuery.proxy () 사용법 (0) | 2020.11.07 |
특정 속성을 가진 모든 요소를 선택하는 방법은 무엇입니까? (0) | 2020.11.07 |