백준 #29 [C] 10951. A+B-4, C언어에서 EOF

K Choi·2022년 2월 21일
3

백준

목록 보기
29/37
post-thumbnail

❔문제: 백준 10951

두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.

➡️입력

입력은 여러 개의 테스트 케이스로 이루어져 있다.
각 테스트 케이스는 한 줄로 이루어져 있으며, 각 줄에 A와 B가 주어진다. (0 < A, B < 10)

⬅️출력

각 테스트 케이스마다 A+B를 출력한다.

예제 입력 1

1 1
2 3
3 4
9 8
5 2

예제 출력 1

2
5
7
17
7

✍️풀이

뭐징 이전 문제보다 쉬운 문제네??
이게 4번이고 이전 문제가 5번이라 그런가보다
생각했지만 while(1)을 쓰면 무한루프를 돌게 되어 이상할텐데데?
아니나 다를까 아래(1번째 제출)와 같이 제출했더니
'출력초과' 오류가 뜹니다.
예상대로 무한루프를 돌아 메모리 할당 범위를 넘어선 것이죠.

C 코드

1번째 제출(출력 초과)

#include <stdio.h>
int main() {
    int A, B;
    while(1){
        scanf("%d %d", &A, &B);
        printf("%d\n", A+B);
    }
    return 0;
}

이렇듯 테스트 케이스에 대한 끝이 제시되지 않은 입력의 경우
뭔가 stop해줄 장치가 필요하겠다, 그게 뭘까 생각해보다가
문제를 다시 보니 EOF에 대해 알아보라고 하네요.

EOF

EOF: End-of-file, 파일 끝, 데이터 입력이 없을 때 실행을 끝냄
입력을 중지하겠음을 알리기 위해 정의된 상수입니다.
<stdio.h> 파일의 41행에 -1 값으로 정의되어 있는 상수입니다.

결국 사용자가 입력하는 두 정수가 EOF가 아닐 때까지만 출력하도록
while문을 작성하면 되겠습니다.

2번째 제출(맞음)

#include <stdio.h>
int main() {
    int A, B;
    while(scanf("%d %d", &A, &B) != EOF)
        printf("%d\n", A+B);
    return 0;
}

이렇게 scanf("%d %d", &A, &B) != EOF를 while문에 작성하면 데이터가 더이상 주어지지 않으면(파일의 끝에 도달하면) 반복문을 종료시킬 수 있습니다.

그런데 찾아보니 scanf함수의 리턴값이 2일 때 루프를 도는 형태로 문제를 해결하면 된다는 말도 있었어요. 왜 그런지 더 알아보니 정수 2개가 지정된 형식(띄어쓰기로 구분하는)으로 입력되지 않으면 프로그램을 종료시킬 수 있기 때문입니다. 그럼 이를 활용해 코드를 하나 더 작성해보겠습니다.

3번째 제출(맞음)

#include <stdio.h>
int main() {
    int A, B;
    while(scanf("%d %d", &A, &B) == 2)
        printf("%d\n", A+B);
    return 0;
}

이 코드와 관련해서는 scanf함수의 리턴값에 대해 조금 알 필요가 있을 것 같아요. 이번 문제를 풀며 scanf함수가 값을 반환한다는 거를 상기시킬 수 있었어요. (지난 학기에 교수님께서 살짝 언급하고 넘어가셔서 필기했었는데 그동안 쓸 일이 없었어요ㅎ)

아무튼 함수는 기본적으로 하나의 값을 반환하고, scanf 함수의 경우 읽어들인 입력의 개수를 반환합니다. 이 사실을 알면 scanf로 입력값을 읽어들일 때 "C6031 반환값이 무시되었습니다."라는 경고가 뜨는 이유가 이해될 거에요.

그런데 이때 '읽어들인 입력의 개수를 반환'한다는 것은 scanf함수 호출 시 사용한 형식 지정자(%로 시작하는 형식) 중 몇개가 처리되었는지를 반환한다는 의미입니다.

예를 들어 아래와 같은 코들를 실행한다고 해보면

int main() {
    int a, b;
    int n = scanf('%d %d', &a, &b);
    printf("%d", n);
    return 0;
}

1 1 입력 시 2가 출력됩니다.
그 이유는 1과 1을 공백을 두고 입력하면 지정된 형식인 정숫값 2개가 정상적으로 입력되었기 때문에 scanf함수는 2를 출력함으로써 %d 2개가 처리되었음을 알려줍니다.

a 1을 입력하면 출력은 어떻게 될까요?
두번째 %d는 정상적으로 입력되어 1이 출력될 거라 생각할 수 있지만 0이 반환됩니다. 그 이유는 scanf함수는 잘못된 입력값을 만나면 입력을 실패로 처리하고 함수를 종료하기 때문입니다. 따라서 첫번째 %d에서 오류가 나 문자 'a'는 표준 입력 버퍼에 남고 두번째 %d를 처리하기 전 scanf함수가 종료됩니다.

1 z를 입력한다면 어떤 출력을 할지 이제 예상해볼 수 있으시겠죠?
네, 1이 출력됩니다.

오늘 scanf함수에 대해 좀더 깊은 지식을 쌓고 가네요.
매우 뿌듯합니다🤗

(오늘은 C++코드는 생략하겠습니다..!)

profile
mbeCoder

3개의 댓글

comment-user-thumbnail
2022년 3월 23일

잘 정리해주셔서 배우고갑니다 ㅎㅎ. 감사합니다

답글 달기
comment-user-thumbnail
2023년 3월 23일

감사합니다! 완전 쉽게 이해되었어요.

답글 달기
comment-user-thumbnail
2023년 11월 16일

감사합니다.

답글 달기

관련 채용 정보