문제 상황
C 언어에서 scanf() 함수로 숫자(정수) 데이터를 입력받은 직후 문자열을 읽으려고 하면, 문자열 입력이 건너뛰어지는 오류가 자주 발생합니다.
원인 분석
scanf()는 표준 입력(stdin)으로부터 형식화된 데이터를 읽어들이는 함수입니다. 그런데 %d로 정수를 입력받을 때 사용자가 Enter 키를 누르면 숫자 값만 소비되고, 나머지 개행 문자(\n)가 입력 버퍼에 그대로 남게 됩니다.
이후 gets()나 scanf("%s", ...) 같은 문자열 입력 함수가 실행되면, 버퍼에 남아 있던 개행 문자를 곧바로 읽어버리고 종료됩니다. 결과적으로 실제 사용자의 이름 입력을 받지 못한 채 다음 문장으로 넘어가 버리는 것입니다.
예제 코드
다음은 학생의 학번(정수)과 이름(문자열)을 입력받는 C 프로그램입니다.
#include <stdio.h>
struct student {
char name[10];
int roll;
} s;
int main(){
printf("Enter information of students:\n");
printf("\nEnter roll number: ");
scanf("%d", &s.roll);
printf("\nEnter name: ");
gets(s.name);
printf("\nDisplaying Information of students:\n");
printf("\nRoll number: %d\t", s.roll);
printf("\nname:%s\t", s.name);
return 0;
}실행 결과
위 프로그램을 실행하면 학번은 정상적으로 입력되지만, 이름 입력 단계는 건너뛰어집니다. 프로그램이 gets() 호출 시점에 버퍼에 남아 있던 개행 문자를 읽어버려 즉시 다음 printf() 문으로 넘어가기 때문입니다.
Enter information of students: Enter roll number: 3 Enter name: // 이름을 입력받지 못하고 건너뜀 Displaying Information of students: Roll number: 3 name: // 빈 문자열 출력
해결 방법
이 문제를 해결하려면 문자열 입력 전에 버퍼에 남아 있는 개행 문자를 제거해야 합니다. 대표적인 해결 방법은 다음과 같습니다.
1. getchar()로 개행 문자 제거
scanf("%d", &s.roll);
getchar(); // 버퍼에 남은 '\n' 제거
gets(s.name);2. 형식 지정자 앞에 공백 추가
scanf("%d", &s.roll);
scanf(" %s", s.name); // %s 앞의 공백이 개행 문자를 무시함3. fgets() 사용 권장
참고로 gets()는 버퍼 오버플로우 위험 때문에 C11 표준에서 제거된 함수입니다. 실무 환경에서는 안전한 fgets() 사용을 권장합니다.
scanf("%d", &s.roll);
getchar(); // 개행 문자 제거
fgets(s.name, sizeof(s.name), stdin);결론
C 언어에서 scanf()로 숫자를 입력받은 후 문자열 입력이 무시되는 오류는, 입력 버퍼에 남은 개행 문자가 원인입니다. getchar()로 개행 문자를 제거하거나 형식 지정자 앞에 공백을 추가하는 것만으로도 간단히 해결할 수 있습니다.