개발/C++

"계속하려면 아무 키나 누르시겠습니까?"를 시뮬레이션하는 방법

MinorMan 2020. 9. 26. 00:49
반응형

<질문>

사용자가 키보드에서 문자를 입력하면 다음 코드 줄로 이동해야하는 C ++ 프로그램을 작성하려고합니다.

내 코드는 다음과 같습니다.

char c;

cin>>c;

cout<<"Something"<

그러나 이것은 어떤 문자를 입력하고 ENTER를 누르면 다음 줄로 이동하기 때문에 작동하지 않습니다.

또는

이것을 사용하면

cin.get() or cin.get(c)

Enter 키를 누르면 다음 줄로 이동합니다.

하지만 키보드에서 눌린 키의 다음 줄로 이동하고 싶었습니다. 어떻게 할 수 있습니까?


<답변1>

Windows의 경우 :

system("pause");

Mac 및 Linux :

system("read");

"계속하려면 아무 키나 누르십시오 ..."를 출력하고 아무 키나 누를 때까지 기다립니다. 그게 당신의 뜻 이었으면 좋겠어요


<답변2>

Windows를 사용하는 경우 Microsoft 런타임 라이브러리의 일부인 kbhit ()을 사용할 수 있습니다. Linux를 사용하는 경우 kbhit을 구현할 수 있습니다 (소스).

#include 
#include 
#include 
#include 

int kbhit(void)
{
  struct termios oldt, newt;
  int ch;
  int oldf;

  tcgetattr(STDIN_FILENO, &oldt);
  newt = oldt;
  newt.c_lflag &= ~(ICANON | ECHO);
  tcsetattr(STDIN_FILENO, TCSANOW, &newt);
  oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
  fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

  ch = getchar();

  tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
  fcntl(STDIN_FILENO, F_SETFL, oldf);

  if(ch != EOF)
  {
    ungetc(ch, stdin);
    return 1;
  }

  return 0;
}

업데이트 : 위의 기능은 OS X에서 작동합니다 (적어도 OS X 10.5.8-Leopard에서 작동하므로 OS X의 최신 버전에서 작동 할 것으로 예상합니다). 이 요점은 kbhit.c로 저장하고 Linux 및 OS X에서 다음을 사용하여 컴파일 할 수 있습니다.

gcc -o kbhit kbhit.c

함께 실행할 때

./kbhit

키를 누르라는 메시지가 표시되고 키를 누르면 종료됩니다 (Enter 또는 인쇄 가능한 키에 국한되지 않음).

@Johnsyweb- "상세한 표준 답변"과 "모든 우려 사항"이 의미하는 바를 자세히 설명해주십시오. 또한 "크로스 플랫폼":이 kbhit () 구현으로 Linux / Unix / OS X / Windows의 C ++ 프로그램에서 동일한 기능을 사용할 수 있습니다. 다른 플랫폼을 참조 할 수 있습니다.

@Johnsyweb에 대한 추가 업데이트 : C ++ 애플리케이션은 밀폐 된 C ++ 환경에 있지 않습니다. C ++의 성공에 대한 큰 이유는 C와의 상호 운용성입니다. 모든 주류 플랫폼은 C 인터페이스로 구현됩니다 (내부 구현에서 C ++를 사용하는 경우에도). 따라서 "레거시"에 대한 이야기는 적절하지 않은 것처럼 보입니다. 게다가 우리가 단일 함수에 대해 이야기하고 있는데 왜 이것을 위해 C ++ ( "C with classes")가 필요합니까? 내가 지적했듯이 C ++로 작성하고이 기능에 쉽게 액세스 할 수 있으며 애플리케이션 사용자는이를 구현하는 방법에 관심이 없을 것입니다.


<답변3>

완전히 이식 가능한 솔루션은 없습니다.

comp.lang.c FAQ의 질문 19.1은 Windows, Unix 계열 시스템, 심지어 MS-DOS 및 VMS를위한 솔루션으로이 문제를 깊이있게 다룹니다.

빠르고 불완전한 요약 :

  • curses 라이브러리를 사용할 수 있습니다. cbreak () 다음에 getch ()를 호출합니다 (Windows 관련 getch () 함수와 혼동하지 마십시오). curses는 일반적으로 터미널을 제어하므로 과잉 일 가능성이 높습니다.
  • ioctl ()을 사용하여 터미널 설정을 조작 할 수 있습니다.
  • POSIX 호환 시스템에서는 tcgetattr () 및 tcsetattr ()이 더 나은 솔루션 일 수 있습니다.
  • Unix에서는 system ()을 사용하여 stty 명령을 호출 할 수 있습니다.
  • MS-DOS에서는 getch () 또는 getche ()를 사용할 수 있습니다.
  • VMS (현재 OpenVMS라고 함)에서는 SMG $ (Screen Management) 루틴이 트릭을 수행 할 수 있습니다.

이러한 모든 C 솔루션은 C ++에서 똑같이 잘 작동합니다. C ++ 관련 솔루션을 모릅니다.


<답변4>

이 기능을 달성하기 위해 Windows와 Linux (그리고 내가 아는 한 MacOS) 모두에서 구현 된 ncurses 라이브러리를 사용할 수 있습니다.


<답변5>

Windows에서이 짧은 프로그램은 목표를 달성합니다. getch는 키를 누를 때까지 콘솔을 일시 중지합니다 (https://www.geeksforgeeks.org/difference-getchar-getch-getc-getche/).

#include
#include

using namespace std;

void  check()
{
    char chk; int j;
    cout<<"\n\nPress any key to continue...";
    chk=getch();
    j=chk;
    for(int i=1;i<=256;i++)
      if(i==j) break;
    clrscr();
}

void main()
{
    clrscr();
    check();
    cout<<"\n\nIt works!";
    getch();
}

getch는 표준 라이브러리의 일부가 아닙니다.


<답변6>

저도 똑같은 일을하고 싶었 기 때문에 당신이 달성하려는 것을 조사했습니다. Vinay에게 영감을 받아 저에게 맞는 글을 썼고 저는 이해합니다. 하지만 저는 전문가가 아니니 조심하세요.

Vinay가 여러분이 Mac OS X를 사용하고 있다는 것을 어떻게 알 수 있는지 모르겠습니다.하지만 대부분의 유닉스 계열 OS에서는 이와 같이 작동합니다. 리소스가 opengroup.org이므로 정말 유용합니다.

기능을 사용하기 전에 버퍼를 플러시하십시오.

#include 
#include         //termios, TCSANOW, ECHO, ICANON
#include      //STDIN_FILENO


void pressKey()
{
    //the struct termios stores all kinds of flags which can manipulate the I/O Interface
    //I have an old one to save the old settings and a new 
    static struct termios oldt, newt;
    printf("Press key to continue....\n");

    //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;

    //two of the c_lflag will be turned off
    //ECHO which is responsible for displaying the input of the user in the terminal
    //ICANON is the essential one! Normally this 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 | ECHO );      

    //Those new settings will be set to STDIN
    //TCSANOW tells tcsetattr to change attributes immediately. 
    tcsetattr( STDIN_FILENO, TCSANOW, &newt);

    //now the char wil be requested
    getchar();

    //the old settings will be written back to STDIN
    tcsetattr( STDIN_FILENO, TCSANOW, &oldt);

}


int main(void)
{
  pressKey();
  printf("END\n");
  return 0;
}

O_NONBLOCK도 중요한 플래그 인 것 같지만 저에게는 아무것도 바뀌지 않았습니다.

좀 더 깊은 지식을 가진 사람들이 이것에 대해 논평하고 조언을 해주면 감사합니다.


<답변7>

Microsoft 전용 함수 _getch를 사용할 수 있습니다.

#include 
#include 
// ...
// ...
// ...
cout << "Press any key to continue..." << endl;
_getch();
cout << "Something" << endl;

<답변8>

이것은 Windows 플랫폼에서 작동합니다. 마이크로 프로세서 레지스터를 직접 사용하고 키 누름 또는 마우스 버튼을 확인하는 데 사용할 수 있습니다.

    #include
    #include
    #include
    void main()
    {
     clrscr();
     union REGS in,out;
     in.h.ah=0x00;
     printf("Press any key : ");

     int86(0x16,&in,&out);
     printf("Ascii : %d\n",out.h.al);
     char ch = out.h.al;
     printf("Charcter Pressed : %c",&ch);
     printf("Scan code : %d",out.h.ah);
     getch();
    }

<답변9>

Visual Studio 2012 또는 이전 버전을 사용하는 경우 getch () 함수를 사용하고 Visual Studio 2013 이상을 사용하는 경우 _getch ()를 사용합니다. #include를 사용해야합니다. . 예:

#include 
#include 

int main()
{
   std::cout << "Press any key to continue. . .\n";
   _getch(); //Or getch()
}

<답변10>

getchar 루틴을 사용할 수 있습니다.

위 링크에서 :

/* getchar example : typewriter */
#include 

int main ()
{
  char c;
  puts ("Enter text. Include a dot ('.') in a sentence to exit:");
  do {
    c=getchar();
    putchar (c);
  } while (c != '.');
  return 0;
}

<답변11>

또한 conio.h에서 getch ()를 사용할 수 있습니다. 다음과 같이 :

...includes, defines etc
void main()
{
//operator
getch(); //now this function is waiting for any key press. When you have pressed its     just     //finish and next line of code will be called
}

따라서 UNIX에는 conio.h가 없기 때문에이 코드로 getch ()를 시뮬레이션 할 수 있습니다 (하지만이 코드는 이미 Vinary에서 작성했습니다. 실패했습니다).

#include 
#include 
#include 

int mygetch( ) {
  struct termios oldt,
             newt;
  int            ch;
  tcgetattr( STDIN_FILENO, &oldt );
  newt = oldt;
  newt.c_lflag &= ~( ICANON | ECHO );
  tcsetattr( STDIN_FILENO, TCSANOW, &newt );
  ch = getchar();
  tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
  return ch;
}

<답변12>

지금 MSDN에서 kbhit () 함수를 찾으면 해당 함수가 더 이상 사용되지 않는다고 표시됩니다. 대신 _kbhit ()을 사용하십시오.

#include 
int main()
{
    _kbhit();
    return 0;
}

<답변13>

#include 
using namespace std;

int main () {
    bool boolean;
    boolean = true;

    if (boolean == true) {

        cout << "press any key to continue";
        cin >> boolean;

    }
    return 0;
}

<답변14>

그냥 system ( "pause"); 명령.

다른 모든 답변은 문제를 복잡하게 만듭니다.

반응형