Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++에서 Enter 키 없이 표준 입력에서 문자를 즉시 읽는 방법

C++ 표준 라이브러리만으로는 개행(Enter)을 기다리지 않고 키 입력을 즉시 읽는 이식 가능한(portable) 방법이 존재하지 않습니다. 운영체제마다 터미널의 동작 방식이 다르기 때문에, 플랫폼별로 다른 접근 방식을 사용해야 합니다.

Windows에서 구현하기 — conio.h의 getch() 함수

Windows에서는 conio(Console I/O) 라이브러리에서 제공하는 getch() 함수를 사용하면 됩니다. 이 함수는 사용자가 누른 문자를 버퍼링 없이 바로 반환해 줍니다.

예제 코드

#include<iostream>
#include<conio.h>
using namespace std;
int main() {
    char c;
    while(1){ // 무한 루프
        c = getch();
        cout << c;
    }
}

위 코드는 사용자가 입력한 문자를 그대로 터미널에 출력합니다. 단, conio.h 헤더는 Windows 전용이므로 이 코드는 Windows 환경에서만 동작합니다.

UNIX/Linux에서 구현하기 — raw 모드 활용

UNIX 계열 시스템(Linux, macOS 등)에서는 터미널을 raw 모드로 전환하여 같은 효과를 얻을 수 있습니다. stty raw 명령어로 터미널의 줄 버퍼링(line buffering)을 비활성화하면, Enter 키를 누르기 전에도 각 키 입력을 즉시 읽을 수 있습니다.

예제 코드

#include<iostream>
#include<stdio.h>
int main() {
    char c;
    // 터미널을 raw 모드로 설정
    system("stty raw");
    while(1) {
        c = getchar();
        // "." 키가 눌리면 종료
        if(c == '.') {
            system("stty cooked");
            exit(0);
        }
        std::cout << c << " was pressed."<< std::endl;
    }
}

이 코드는 누른 키마다 "○ was pressed."라는 메시지를 출력하며, 마침표(.)를 누르면 터미널을 원래 상태(cooked 모드)로 복구한 뒤 프로그램을 종료합니다.

주의 사항

  • raw 모드 복구: 프로그램이 비정상적으로 종료되면 터미널이 raw 모드로 남아 있을 수 있습니다. 종료 전 반드시 stty cooked로 되돌려 주세요.
  • system() 호출의 한계: 예제에서는 편의상 system()을 사용했지만, 실제 프로젝트에서는 termios API(tcgetattr(), tcsetattr())를 직접 사용하는 것이 더 안전하고 효율적입니다.
  • 크로스 플랫폼 대안: Windows와 UNIX를 모두 지원해야 한다면 조건부 컴파일(#ifdef _WIN32)로 두 방식을 분기 처리하거나, ncurses 같은 크로스 플랫폼 라이브러리를 고려할 수 있습니다.