scanf 로 문자열을 받고 나면 공백으로 구분되서 남은 문자들이 아직 버퍼에 남아 있기 때문에…
fflush(stdin);
을 해줌으로써 버퍼를 비워주는 프로그래밍 기법이 있다.
하지만 이것은 엄밀히 말하면 틀린것이다. 더 정확히 이야기하자면 VC 에서만(아마도..) 된다.
사용자들의 편의를 위해 VC에서 확장의 개념으로 만든것이라 생각하면 이해가 쉬울 것이다.
그렇다면 왜 이것이 안되는 것일까?
C FAQ 12.26을 보면 다음과 같은 말이 나온다.
C 언어 표준에 따르면,
fflush()는 output stream에 대해서만 동작합니다.
“flush”라는 정의가 buffering된 문자들을 쓰는 것을
완료시킨다는12.15 것이므로 문자를 취소시키는 것(discard)과는 아무런 관계가 없습니다.
따라서
입력 스트림의 입력을 무시하는 기능과는 전혀 상관이 없습니다.아직 읽지 않은 문자(unread characters)들을 stdio input stream에서
무시하는(discard) 표준 방법은 존재하지 않습니다.
어떤 컴파일러 회사들은 fflush(stdin)이 읽지 않은 문자들을 취소할 수
있도록 라이브러리를 제공하기도 하지만, 이식성이 뛰어난 프로그램을
만들려면 절대로 써서는 안되는 기능입니다.
(어떤 stdio 라이브러리는 fpurge나 fabort를 같은 기능으로
제공하기도 하지만, 마찬가지로 표준은 아닙니다.)
또한 input buffer를 flush하는 것이 꼭 해결책이라고 할 수도 없습니다.
왜냐하면
일반적으로 아직 읽히지 않은 입력은 OS-level input buffer에
존재하기 때문입니다.Input을 flush할 방법이 필요하다면 (질문
19.1과
19.2에 나온 것처럼)
시스템 의존적인 방법을 찾아야 할 것입니다.
게다가 사용자가 매우 빠른 속도로 입력하고 있고, 여러분의 프로그램이
그 입력을 무시해버릴 수 있다는 것을 꼭 염두에 두어야 합니다.또는
n
이 나오기 전까지 문자를 읽어서 무시하거나,
curses에서 제공하는 루틴인 flushinp()를 쓰면 됩니다.
덧붙여 질문
19.1,
19.2도 참고하시기 바랍니다.
즉 원래 fflush() 함수는 output stream에 대해서만 동작하는 함수이기 때문에 input stream에는 사용할 수 없는 것이고, 또 그런 함수는 존재하지 않는다는 것이다.(물론 표준이야기이다.)
그렇다면 어떻게 해야할까?
이런 식으로 바로 아래 라인에 다시 입력을 받는 함수를 호출에 버퍼에 남아있는 문자들을 비워주는 것도 하나의 좋은 보기가 될 수 있다.