c언어/C언어 개념정리

C언어의 표준 입출력 라이브러리 <studio.h> 2. scanf()

코드라니(CODERANY) 2024. 12. 2. 21:49

C 언어의 <stdio.h> 라이브러리는 표준 입출력 기능을 제공하는 함수들을 포함하고 있습니다. 이 라이브러리를 사용하면 콘솔과 파일 간의 데이터 입출력을 손쉽게 처리할 수 있습니다. 

 

다른 입출력 라이브러리보기

더보기

1. printf() 

2. scanf() :  현재글

3. fopen()

4. fclose()

5. fgets()

6. fputs()

7. fprintf()

8. fscanf()

1. scanf() 함수의 정의

사용자가 입력한 데이터를 읽어와 지정된 변수에 저장하는 함수입니다.

키보드와 같은 표준 입력 스트림(콘솔)에서 데이터를 읽어오는 데 사용됩니다.

 

형식

int scanf(const char *format, &...);

format: 입력할 데이터의 형식을 지정하는 문자열입니다. 형식 지정자는 % 기호로 시작하며, 이후에 데이터 타입을 나타내는 문자가 옵니다.
&...: 입력받은 값이 저장될 변수의 주소입니다. 여러 개의 변수를 한 번에 입력받을 수 있습니다.


2. 주요 기능

다양한 데이터 타입 지원: 정수, 실수, 문자, 문자열 등 다양한 데이터 타입을 입력받을 수 있습니다.
가변 인자: 여러 개의 변수를 한 번에 입력받을 수 있으며, 각 변수에 저장할 수 있습니다.
형식 지정자 사용: 입력할 데이터의 형식을 명시적으로 지정하여 입력을 관리할 수 있습니다.

 

3. 형식 지정자

정수형

%d : 10진 정수 (int)
%i : 10진 정수 (int, 8진수 및 16진수도 입력 가능)
%u : 부호 없는 10진 정수 (unsigned int)
%o : 8진수 (unsigned int)
%x : 16진수 (unsigned int, 소문자)
%X : 16진수 (unsigned int, 대문자)
부동 소수점형

%f : 부동 소수점 수 (float)
%lf : 부동 소수점 수 (double)
%e : 지수 형식 (float)
%E : 지수 형식 (float, 대문자)
%g : 자동 선택 (float)
%G : 자동 선택 (float, 대문자)
문자형

%c : 문자 1개 (char)
%s : 문자열 (char 배열)
포인터형

%p : 포인터 주소

 

4. 사용 예제

4.1 기본 사용

#include <stdio.h>

int main() {
    int num;
    printf("Enter an integer: ");
    scanf("%d", &num); // 사용자로부터 정수를 입력받아 num에 저장
    printf("You entered: %d\n", num);
    return 0;
}

 

사용자는 정수를 입력하고, 입력된 값은 num 변수에 저장됩니다. 이후, 입력된 값이 출력됩니다.

 

4.2 여러 값 입력받기

#include <stdio.h>

int main() {
    int a, b;
    printf("Enter two integers: ");
    scanf("%d %d", &a, &b); // 두 개의 정수를 입력받아 a와 b에 저장
    printf("You entered: %d and %d\n", a, b);
    return 0;
}

사용자는 두 개의 정수를 입력하고, 이 값들은 각각 a와 b에 저장됩니다.

 

4.3 문자열 입력받기

#include <stdio.h>

int main() {
    char name[50];
    printf("Enter your name: ");
    scanf("%s", name); // 사용자로부터 문자열 입력받아 name 배열에 저장
    printf("Hello, %s!\n", name);
    return 0;
}

 사용자가 입력한 이름이 name 배열에 저장되고, 이후에 출력됩니다.

 

5. 오류 처리

scanf() 함수는 사용자가 잘못된 형식의 데이터를 입력할 경우 입력이 실패할 수 있습니다. 

이 경우, scanf()는 성공적으로 읽은 항목의 수를 반환합니다. 이를 통해 입력 오류를 처리할 수 있습니다.

#include <stdio.h>

int main() {
    int num;
    printf("정수를 입력하세요: ");
    if (scanf("%d", &num) != 1) { // 정수가 아니면 1을 반환
        printf("입력이 잘못되었습니다! 정수를 입력하세요.\n");
        // 1을 반환하면 나오는 문구
        return 1; 
    }
    printf("입력한 수: %d\n", num);
    return 0;
}

 

6. 성능 측면

scanf()는 사용하기 간편하지만, 입력 버퍼를 처리하는 방식 때문에 성능이 저하될 수 있습니다. 

특히, 사용자 입력을 기다리는 동안 프로그램이 멈추기 때문에, 대량의 입력을 처리할 때는 성능에 영향을 줄 수 있습니다.

6.1 입력 버퍼
scanf()는 입력 버퍼를 사용하여 데이터를 처리합니다. 그러나 버퍼에 남아 있는 데이터가 다음 scanf() 호출에 영향을 줄 수 있습니다. 예를 들어, scanf()로 문자열을 읽은 후, 다음 scanf() 호출에서 여전히 버퍼에 남아 있는 개행 문자 (\n)를 처리하지 않으면 예상치 못한 결과가 발생할 수 있습니다.

#include <stdio.h>

int main() {
    char name[50];
    int age;

    printf("Enter your name: ");
    scanf("%s", name);
    printf("Enter your age: ");
    scanf("%d", &age); // 개행 문자가 남아 있을 경우 문제가 발생할 수 있음
    printf("Name: %s, Age: %d\n", name, age);
    return 0;
}

정상작동

개행문자가 남은 경우(오류 발생, 반응 없음)

7. 안전한 입력을 위한 대안

scanf()는 입력 처리에 있어 몇 가지 단점을 가지고 있습니다.

입력의 길이를 제한할 수 없고, 버퍼 오버플로우의 위험이 있습니다.

안전한 입력을 위해 다음과 같은 방법이 있습니다.

 

7.1 fgets()
fgets() 함수는 문자열을 안전하게 입력받을 수 있는 방법입니다. 이 함수는 지정된 크기만큼 입력을 읽어오며, 버퍼 오버플로우를 방지합니다.

#include <stdio.h>

int main() {
    char name[50];
    printf("Enter your name: ");
    fgets(name, sizeof(name), stdin); // 문자열 입력받기
    printf("Hello, %s", name);
    return 0;
}

(프로그램 이슈로 영어는 그냥 잘리고 끝인데, 한국어는 물음표가 뜬다...)

 

7.2 sscanf()
sscanf() 함수는 문자열에 있는 데이터를 형식화하여 읽어오는 함수입니다. 이는 scanf()와 유사하지만, 문자열에서 직접 데이터를 읽습니다.

#include <stdio.h>

int main() {
    char input[100];
    int num;

    printf("Enter a number: ");
    fgets(input, sizeof(input), stdin); // 문자열 입력받기
    sscanf(input, "%d", &num); // 문자열에서 정수 읽기
    printf("You entered: %d\n", num);
    return 0;
}

 

C 언어의 int 타입은 보통 -2,147,483,648에서 2,147,483,647까지의 값을 가질 수 있습니다. 

따라서 2,147,483,648을 입력하면 오류가 발생할 수 있습니다.