C의 입력 버퍼를 비우는 방법
글쓴이: HDNua / 작성시간: 금, 2014/11/21 - 3:49오후
안녕하세요. 휴가 나온 군인입니다.
제가 봤던 입문서에서도 그랬지만 Windows에서 입력 버퍼를 비울 때는
fflush(stdin)을 호출하여 입력 버퍼를 제법 간단히 비울 수 있습니다.
다만 이건 Windows에서만 가능한 것이고 다른 운영체제에선 정의되지 않은 동작이다라는 설명이 붙어있군요.
그래서 저는 모든 운영체제에 범용적으로 적용 가능한 clearReadBuffer를 만드려고 검색도 해보고 많은 노력을 했습니다.
1번 방법
void clearReadBuffer() { while (getchar() != '\n'); }
가장 널리 알려진 방법이지만 입력 버퍼가 이미 비어있는 경우에 사용자로부터 입력을 받기 위해 대기하는 게 가장 큰 문제입니다.
엔터를 두 번 이상 치던지 일부러 잘못된 입력을 넣던지 해야 제대로 동작하는 경우가 있습니다.
2번 방법
void clearReadBuffer() { if (stdin->_cnt) while (getchar() != '\n'); }
입대 전까지 애용하던 입력 버퍼 삭제 함수입니다. 아주 잘 동작하지만
Mac OS X에서는 _cnt 멤버의 역할을 _r 멤버가 했기 때문에 운영체제가 달라지면 매번 이 함수를 수정해야 합니다.
3번 방법
int isBufferEmpty(FILE *stream) { return (stream->_cnt > 0); } void clearReadBuffer() { while (!isBufferEmpty(stdin)) getchar(); }
지금 새로 고안했는데, 개행 이후에도 문자가 남아있는 경우에도 확실하게 입력 버퍼를 비울 수 있습니다.
다만 2번 방법에서 존재하던 문제는 해결되지 않았습니다. (서로 분리한다면 2번보다야 적게 수정할 수 있지 않을까 합니다.)
4번 방법
void clearReadBuffer() { fseek(stdin, 0, SEEK_END); }
인터넷을 검색하다 stackoverflow에서 찾은 아주 참신한 방법이지만, 이해하기 힘들어 모든 운영체제에서 반드시 옳다고 할 수가 없습니다.
https://stackoverflow.com/questions/7898215/how-to-clear-input-buffer-in-c/9750394#9750394
(링크는 위. 본인도 리눅스에서 이것이 항상 옳은지 확인하지 못했다고 합니다.)
-----
1. 3번 방법에서 isBufferEmpty를 대체할 표준 함수가 C 라이브러리에 정의되어있을까요?
처음에는 입력 버퍼의 끝에 도달했다면 feof로 검출할 수 있을 줄 알고 이를 이용해봤지만 뜻대로 되지 않습니다.
2. 4번 방법이 항상 옳다면 왜 그런지 설명해주시면 감사하겠습니다. 버퍼의 끝으로 포인터를 옮기는 것 같은데
컴파일러 구현에 따라 다를 수도 있는 내용이 아닌지, 아니면 그렇게 구현하는 것이 표준인지 궁금합니다.
3. C에서 입력 버퍼를 비우는 더 멋진 방법을 알고 계시는 분은 답변 부탁합니다.
이런 이유로 KLDP에 도움을 청합니다.
읽어주셔서 감사합니다.
Forums:
int isBufferEmpty(FILE
이런 방법도 있습니다.
그냥 isBufferEmpty() 함수를 시스템 별로
그냥 isBufferEmpty() 함수를 시스템 별로 만드는 것 외엔 방법이 없을까요?
궁금해서 문서를 계속 뒤지고 있는데 도움이 될 만한 어떤 문서도 찾을 수가 없습니다.
문자 배열에 입력 버퍼의 내용을 모두 옮긴 다음 이 배열을 체크할 수도 있지만
입력 버퍼가 비어있는지 확인하는, 간단하면서도 '분명 엄청나게 유용한' 이런 함수를
구현하지 않았을 것 같지 않습니다.
뭐 없다면 어쩔 수 없는데 답답하네요.
저는 이렇게 생각했습니다.
if (isatty(fileno(stream)))
답변 감사합니다.
그냥 fflush가 안 동작하니 tcflush로 바꾼 게 전부네요.
tcflush를 찾아보니 리눅스에서 동작하도록 되어있다는데 좀 더 찾아봐야겠습니다.
저는 이렇게 생각했습니다.
괜한 것을 던진 것 같네요. tcflush() 에
괜한 것을 던진 것 같네요.
tcflush() 에 집중하지 말고 POSIX terminal 의 canonical mode 에 대해 공부하시면 그나마 뭔가 좀 남는 삽질이었다고 자위하실 수 있을 겁니다.
먼저, 왜 입력 버퍼를 비우는 기능이 필요한지 생각해
먼저, 왜 입력 버퍼를 비우는 기능이 필요한지 생각해 보세요. 그런 기능 없이 충분히 프로그램 작성할 수 있을 텐데요.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
중요한 건 아니고.. 그냥 궁금해서 한
중요한 건 아니고.. 그냥 궁금해서 한 질문이었습니다.
MSP Code Challenge라고 학교 과제 비스무리한 걸 하는데 잘못된 입력으로 오류가 나면 틀린 답이라고 되어있어서
어느 환경에서나 반드시 입력 버퍼를 비울 수 있으면 좋겠다는 생각이 문득 들어서요.
결국엔 그냥 직접 버퍼를 만들어 문자열로 받고 변수로 변환한 다음 이 버퍼를 비우는 식으로 해결했습니다.
저는 이렇게 생각했습니다.
댓글 달기