ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [C/C++] scanf vs fgets
    프로그래밍/C,C++ 2020. 2. 28. 14:53

    백준 문제 풀이를 통해 scanf와 fgets의 차이점을 알아봅시다.

     

    문제 11718, 11719

    입력 받은 대로 출력하는 프로그램을 작성하시오.

     

    입력

    입력이 주어진다. 입력은 최대 100줄로 이루어져 있고, 알파벳 소문자, 대문자, 공백, 숫자로만 이루어져 있다. 각 줄은 100글자를 넘지 않으며, 빈 줄은 주어지지 않는다. 또, 각 줄은 공백으로 시작하지 않고, 공백으로 끝나지 않는다.

     

    출력

    입력받은 그대로 출력한다.

     

    출처 : 백준(11718)

     

    출처 : 백준(11719)

     

    풀이

    문자열을 입력받기 위해서 scanf 대신에 fgets를 이용하여 문제를 해결했습니다. 

    scanf는 엔터, 탭, 스페이스 등의 공백을 문자열로 처리하지 않기 때문 이 문제를 해결하기 위한 수단으로 적합하지 않다고 생각했습니다. scanf와 fgets의 차이점의 이해를 돕기 위해서 다음과 같이 간단한 예제를 준비했습니다.

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <stdio.h>
     
    int main(void){
        freopen("input.txt","rt",stdin);
        char str[100];
        scanf("%s",&str);
    //    fgets(str,100,stdin);
        printf("%s",str);
        return 0;
    }
    cs

     

    input.txt 라는 파일에는 'love is love' 라는 문자열이 저장되어 있고 이를 scanf와 fgets로 읽어왔을 때 결과가 어떻게 다른지 확인해보겠습니다.

     

    scanf의 결과(위) / fgets의 결과(아래)

    위의 결과에서처럼 scanf는 스페이스를 문자열로 처리하지 않으므로 Love까지만 출력된 것을 확인할 수 있고 그에 비해 fgets는 스페이스까지 모두 문자열로 처리하여 Love is love를 모두 출력한 결과를 확인할 수 있습니다.

     

    그렇다면 위의 코드에서 문제의 예제를 복사해서 붙여넣으면 올바른 결과가 출력될까요? 그렇지 않습니다.

     

    복사한 입력 예제중에서 Hello만 출력된 결과를 확인할 수 있습니다. 그 이유는 무엇일까요? 이를 이해하기 위해서는 fgets 입력의 종료 조건에 대해서 알고 계셔야합니다.

     

    fgets의 입력 종료 조건은 다음과 같습니다.

     

    1. 개행('\n')을 만날 때

    2. 최대입력문자수-1까지 읽을 때 (NULL, '\0')

    3. EOF가 입력될 때 (Ctrl + Z)

     

    위의 결과는 1번 개행을 만났기 때문에 원하는 입력을 다 받기전에 종료된 것 입니다. 따라서 원하는 결과물을 출력하기 위해선 약간의 코드를 수정하여 2번 조건을 만족하게끔 만들어야합니다.

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <stdio.h>
     
    int main(void){
        freopen("input.txt","rt",stdin);
        char str[100];
        while(fgets(str,100,stdin)!=NULL){
                printf("%s",str);
        }
        return 0;
    }
    cs

     

    위의 조건을 통하여 개행을 만나도 NULL을 만나기전까진 계속 입력받은 문자열을 출력할 수 있습니다.

     

    출력 결과

     

    채점 결과

     

    채점 결과(11718번)
    채점 결과(11719번)

     

    ※ 채점할 때는 freopen("input.txt","rt",stdin); 부분을 주석처리 해주셔야 합니다!

    댓글

Designed by Tistory.