Wednesday, October 04, 2006
C언어] (Yes-No) (Y-N) (+Cancel) 선택 묻기 사용자 입력받기 - 예/아니오
콘솔 프로그램(GUI가 아닌 텍스트 모드 프로그램)에서, 사용자에게, 예/아니오(Y/N)를 묻는 함수입니다. Y/N 이외의 키를 누르면, Y/N 키 중의 하나를 입력할 때까지 다시 묻습니다.
C언어는 물론이고 어떤 언어에서도 이런 세세한 함수까지 제공하지 않기에, 프로그래머가 직접 만들어서 사용해야 하는데, 의외로 경우의 수가 많아서 좀 까다로운 편입니다.
여기서 소개하는,
int getYesNoKey(void);
는 Y/N 키 둘 중의 하나를 대소문자 구분없이 입력받아서 판단하는 것이고,
int getYesNoCancelKey(void);
이것은 "예/아니오/취소" 3가지 경우의 선택을 받아서 판단합니다.
대소문자 구분없이 Y/N/C 키를 받되, Esc키 즉 취소키도 C와 동등하게 취급했습니다.
참고로 아래의 소스는 비주얼C++에서 테스트되었습니다.
파일명: 0.cpp
실행 결과:
소스 주석문에서 warning C4715: 'getYesNoKey' : not all control paths return a value 이런 경고는, "반환값이 있는 함수는 항상 반환값이 있어야 하는데, 특수한 조건에서만 반환값이 있다는" 경고입니다. 이런 경고가 나오지 않게끔 return -1; 이런 불필요한 줄을 넣었습니다.
사용자가 YN 이 아닌 엉뚱한 키를 누를 경우를 대비해서 무한 루프를 돌려야 하는데, 그냥 while(1) 이렇게 무한 루프를 만들면 warning C4127: conditional expression is constant (조건문이 상수로 되어 있다) 라는 워닝이 나오기에, while((key = getch()) != NULL) 이렇게 해주었습니다.
getch() 는 표준입력으로부터 간접적으로 입력받는 것이 아니라 키보드로부터 직접 입력을 받습니다. 그래서 입력받은 키를 화면에 출력(에코)하지 않습니다. getch()를 사용하지 않으면, 사용자가 엉뚱한 키를 눌렀을 때에도 그 키가 화면에 출력되기에 좀 지저분해집니다. 그래서 getch()를 사용했습니다. getch() 함수는 conio.h 에 정의되어 있습니다.
참고로, Esc키의 아스키 코드 값이 0x1B 입니다.
C언어는 물론이고 어떤 언어에서도 이런 세세한 함수까지 제공하지 않기에, 프로그래머가 직접 만들어서 사용해야 하는데, 의외로 경우의 수가 많아서 좀 까다로운 편입니다.
여기서 소개하는,
int getYesNoKey(void);
는 Y/N 키 둘 중의 하나를 대소문자 구분없이 입력받아서 판단하는 것이고,
int getYesNoCancelKey(void);
이것은 "예/아니오/취소" 3가지 경우의 선택을 받아서 판단합니다.
대소문자 구분없이 Y/N/C 키를 받되, Esc키 즉 취소키도 C와 동등하게 취급했습니다.
참고로 아래의 소스는 비주얼C++에서 테스트되었습니다.
키보드로, Y/N 과 Y/N/C 입력 받기 예제
파일명: 0.cpp
#include <stdio.h>
#include <conio.h>
int getYesNoKey(void);
int getYesNoCancelKey(void);
void main(void) {
int test;
printf("Yes/No Test: 할까요? 말까요? (Y/N)? ");
if (getYesNoKey()) {
puts("Y 를 누르셨군요.");
}
else {
puts("N 을 누르셨군요.");
}
printf("Yes/No/Cancel Test: 할까요? 말까요? 또는 아예 취소할까요 (Y/N/C)? ");
test = getYesNoCancelKey();
if (test == 1) {
puts("Y 를 누르셨군요.");
}
else if (test == 0) {
puts("N 을 누르셨군요.");
}
else if (test == 2) {
puts("C 또는 Esc 키를 눌러 취소하셨군요.");
}
}
int getYesNoKey(void) {
int key;
while((key = getch()) != NULL) {
if (key == 'y' || key == 'Y') {
puts("Y");
return 1; // 참을 반환
}
else if (key == 'n' || key == 'N') {
puts("N");
return 0; // 거짓을 반환
}
}
return -1; // 이 줄이 없으면, warning C4715: 'getYesNoKey' : not all control paths return a value
}
int getYesNoCancelKey(void) {
int key;
while((key = getch()) != NULL) {
if (key == 'y' || key == 'Y') {
puts("Y");
return 1; // 참을 반환
}
else if (key == 'n' || key == 'N') {
puts("N");
return 0; // 거짓을 반환
}
else if (key == 'c' || key == 'C' || key == 0x1B) {
puts("C");
return 2; // 참을 반환 (다만 값이 다름)
}
}
return -1; // 이 줄이 없으면, warning C4715: 'getYesNoKey' : not all control paths return a value
}
#include <conio.h>
int getYesNoKey(void);
int getYesNoCancelKey(void);
void main(void) {
int test;
printf("Yes/No Test: 할까요? 말까요? (Y/N)? ");
if (getYesNoKey()) {
puts("Y 를 누르셨군요.");
}
else {
puts("N 을 누르셨군요.");
}
printf("Yes/No/Cancel Test: 할까요? 말까요? 또는 아예 취소할까요 (Y/N/C)? ");
test = getYesNoCancelKey();
if (test == 1) {
puts("Y 를 누르셨군요.");
}
else if (test == 0) {
puts("N 을 누르셨군요.");
}
else if (test == 2) {
puts("C 또는 Esc 키를 눌러 취소하셨군요.");
}
}
int getYesNoKey(void) {
int key;
while((key = getch()) != NULL) {
if (key == 'y' || key == 'Y') {
puts("Y");
return 1; // 참을 반환
}
else if (key == 'n' || key == 'N') {
puts("N");
return 0; // 거짓을 반환
}
}
return -1; // 이 줄이 없으면, warning C4715: 'getYesNoKey' : not all control paths return a value
}
int getYesNoCancelKey(void) {
int key;
while((key = getch()) != NULL) {
if (key == 'y' || key == 'Y') {
puts("Y");
return 1; // 참을 반환
}
else if (key == 'n' || key == 'N') {
puts("N");
return 0; // 거짓을 반환
}
else if (key == 'c' || key == 'C' || key == 0x1B) {
puts("C");
return 2; // 참을 반환 (다만 값이 다름)
}
}
return -1; // 이 줄이 없으면, warning C4715: 'getYesNoKey' : not all control paths return a value
}
실행 결과:
D:\Z>cl 0.cpp && 0.exe
0.cpp
Yes/No Test: 할까요? 말까요? (Y/N)? Y
Y 를 누르셨군요.
Yes/No/Cancel Test: 할까요? 말까요? 또는 아예 취소할까요 (Y/N/C)? C
C 또는 Esc 키를 눌러 취소하셨군요.
D:\Z>
0.cpp
Yes/No Test: 할까요? 말까요? (Y/N)? Y
Y 를 누르셨군요.
Yes/No/Cancel Test: 할까요? 말까요? 또는 아예 취소할까요 (Y/N/C)? C
C 또는 Esc 키를 눌러 취소하셨군요.
D:\Z>
소스 주석문에서 warning C4715: 'getYesNoKey' : not all control paths return a value 이런 경고는, "반환값이 있는 함수는 항상 반환값이 있어야 하는데, 특수한 조건에서만 반환값이 있다는" 경고입니다. 이런 경고가 나오지 않게끔 return -1; 이런 불필요한 줄을 넣었습니다.
사용자가 YN 이 아닌 엉뚱한 키를 누를 경우를 대비해서 무한 루프를 돌려야 하는데, 그냥 while(1) 이렇게 무한 루프를 만들면 warning C4127: conditional expression is constant (조건문이 상수로 되어 있다) 라는 워닝이 나오기에, while((key = getch()) != NULL) 이렇게 해주었습니다.
getch() 는 표준입력으로부터 간접적으로 입력받는 것이 아니라 키보드로부터 직접 입력을 받습니다. 그래서 입력받은 키를 화면에 출력(에코)하지 않습니다. getch()를 사용하지 않으면, 사용자가 엉뚱한 키를 눌렀을 때에도 그 키가 화면에 출력되기에 좀 지저분해집니다. 그래서 getch()를 사용했습니다. getch() 함수는 conio.h 에 정의되어 있습니다.
참고로, Esc키의 아스키 코드 값이 0x1B 입니다.
tag: cpp
C언어 | C/C++ (Visual C++)
<< Home