공백문자를 포함한 문자열을 받기 위해 주로 사용하는 gets함수

gets 함수를 사용할때 scanf를 함께 사용하는 경우 주의할 점이 있다.


gets함수는 (1) 입력버퍼가 차있는 경우 첫번째 글자를 출력

(2) 입력버퍼가 비어있는 경우 입력을 요구, 입력받은 글자의 첫번째 글자를 출력


gets를 쓰는 경우 대부분 (2)의 결과를 원해서 사용한다.


이때 gets를 쓰기 이전에

scanf로 먼저 값을 입력 받은 후 gets로 추가로 값을 입력받으려고 하면

제대로 동작하지 않는 에러가 발생한다.


scanf함수를 사용할 때 값을 입력한뒤 개행문자(enter)를 누르게 되는데

값은 넘어가고 개행문자는 입력버퍼에 남아있게되어

다음에 gets 함수를 사용하는데 버퍼에 남아있는 개행문자를 꺼내오게된다.

그리고 이 개행문자를 '사용자 입력의 끝'으로 인식하기 때문에

gets 함수가 동작하지 않고 넘어가게 되는 것이다.



(ex)

char name[32] = {0};

int age = 0;


printf("나이를 입력 : ");

scanf("%d",&age);


printf("이름을 입력 : ");

gets(name);


printf("나이 : %d, 이름 : %s\n", age, name);


(result)

나이를 입력 : 99 (입력)

이름을 입력 : 나이 : 99, 이름 :


*버퍼에 개행문자가 남아있어 gets함수가 동작하지 않고 넘어갔다





문제해결을 위해서는 (1) fflush 함수를 이용 (2) 형식문자의 추가 두가지 방법이 존재한다.


(1) fflush 함수의 경우 원래 '출력 버퍼'를 비우는 함수이지만(C언어의 표준) 

MS윈도우가 표준을 준수하지 않아 입력버퍼를 비우는 역할을 하게 되었다.

따라서 표준을 준수한 UNIX,Linux에서는 동작하지 않는다.

반대로 UNIX,Linux에서는 fpurge()함수를 이용해 초기화가 가능하지만

윈도우에서는 사용이 불가능하다.

*현재 VS2015 버전에서는 제대로 동작하지 않는다.


(2) 두번째 방법으로는 형식문자의 추가가 있다.

형식문자에서 형식문자 %기호와 형식문자 사이에 위치한 별표(*)는 '버림'의 의미이다.

따라서 위의 코드를 scanf("%d%*c",&age);로 수정하면

정수와 함께 문자 하나(개행문자)를 꺼내 버린다. 다양한 환경에서 동작하기 때문에

두번째 방법을 익히는 것이 좋다




출처 : 독하게 시작하는 C프로그래밍

+ Recent posts