Computer >> 컴퓨터 >  >> 프로그래밍 >> C 프로그래밍

C 언어에서 scanf() 사용 시 발생하는 일반적인 오류와 해결 방법

문제 상황

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()로 개행 문자를 제거하거나 형식 지정자 앞에 공백을 추가하는 것만으로도 간단히 해결할 수 있습니다.