문자열을 입력받거나 혹은 데이터를 입력받을때 scanf()와 gets()를 주로 사용한다.
gets()는 공백문자를 포함하는 한줄의 문자열을 읽는다. 그리고 엔터키, 즉 줄바꿈문자('\n')는 포함되지 않으며 자동으로 NULL문자('\0')를 추가한다. 그리고 buffer라는 저장소에 저장된다.
반면에 scanf()는 하나의 단어밖에 입력받지 못한다. 공백을 포함하지 못한다.
표준입출력함수
printf, scanf, putchar, getchar, puts, gets같은 것들은 '표준 입출력 함수'라고한다.
이런 표준 입출력 함수를 사용할 때는 buffer라는 것을 제공받게 된다.
그렇다면 buffer는 뭘까?buffer란 여분의 임시 메모리 공간이다.
우리가 scanf, gets함수를 써서 데이터를 입력했다고 가정하자.
그러면 엔터를 누르는 순간 데이터는 바로 프로그램안으로 읽혀지는것이 아니라 buffer로 들어간다.
그리고 buffer에 일정데이터가 모이면 그때 프로그램안으로 데이터가 들어간다.
그렇다면 버퍼는 왜 사용하는가?
성능 향상이 목적이다. 데이터를 하나씩 보내는게 아닌, 모았다가 한번에 보냄으로써 효율이 좋아진다.
scanf와 gets를 함께 사용할때 어떤 문제점이 있을까?
#include <stdio.h>
int main(void)
{
int a;
char name[10];
scanf("%d", &a);
gets(name);
printf("%d\n", a);
printf("%s\n", name);
return 0;
}
scanf로 정수형 변수 a에 값을 할당하고, gets로 문자열 name에 문자열을 할당한다. 하지만 우리의 의도한 방법대로 작동하지 않는다.
1을 입력하고 name에 문자열을 입력해야하는데, 바로 1이 출력되어버린다. 즉 gets()가 동작하지 않은 것이다. 왜그럴까?
scanf에서 값을 입력하고 엔터를 누른다. 그 후에, 데이터들만이 프로그램으로 들어가게되고, 개행문자('\n')만이 버퍼에 남게된다. gets()는 버퍼에 아직 남아있는 개행문자를 인식하고 입력한다. 그래서 우리는 gets()를 이용할 수 없는 것이다.
그렇다면 이 오류를 해결하기 위해선 어떻게 해야할까?
%*c를 삽입하면된다.
scanf("%d%*c", &a);
gets(name);
%*c에서 *의 의미는 '버림'이라는 뜻이다.
즉, 문자형으로 들어오는 값을 하나 버린다.라는 의미로, 정수를 입력하고 엔터를 누를때, (개행문자, '\0')를 버리면서 버퍼로 들어가지않는다. 버퍼에는 데이터들만이 존재하게 되고, 데이터들이 버퍼에서 프로그램으로 넘어간 후에는 버퍼에 아무것도 남지 않게된다. 그래서 우리는 gets()를 정상적으로 사용할 수 있다.