알고리즘/백준(BOJ) 문제풀이

C++ cin 초기화, 입력 버퍼 비우는 법 : ignore 함수 (BOJ 4458)

restudy 2022. 3. 20. 08:49
반응형

이 포스트에서는 cin 입력 버퍼를 비우고 초기화하는 방법에 대해 다루고 있습니다.

 

적절한 설명을 위해 프로그래밍 문제 사이트 백준 Online Judge(BOJ)의 4458번 : '첫 글자를 대문자로' 문제의 풀이 코드를 함께 활용하도록 하겠습니다.

 

 

먼저 중요한 차이부터 설명드리겠습니다.

 

예를 들어 문자열을 한 줄씩 반복해서 받을 때, 개행 문자 '\n'가 마지막에 남아있기 때문에 이를 비우기 위해서 일반적으로 cin.clear()를 사용해왔는데, clear 함수는 사실은 입력 버퍼를 비우는 것이 아닌, stream을 good state로 돌려주는 함수라고 합니다.

 

따라서 버퍼를 명확히 비우기 위해서는 ignore 함수를 사용하는 것이 더 정확합니다.

이 때 cin.ignore()로 사용하면 문자 한 개만큼 버퍼를 비우는 것입니다.

따라서 더 긴 길이로 버퍼를 비우기 위해서는 cin.ignore(10)과 같이 사용하면 10개 문자만큼의 버퍼를 비울 수 있는 것입니다.

 

이제 문제 풀이를 하면서 정확히 어떤 상황에 사용하는지 설명드리도록 하겠습니다.

 

 

4458번 : 첫 글자를 대문자로

 

위와 같이 공백을 포함하여 문자열이 입력되면 그 줄에 해당하는 문자열의 모든 첫 문자를 대문자로 바꾸는 문제입니다.

생각해보면 간단히 풀이할 수 있는 쉬운 문제입니다.

그러나 이 문제의 경우 버퍼를 비우지 않고 일반적으로 처리를 하면 항상 1개 문자열만큼 더 읽혀서 정확한 처리가 어렵습니다.

 

왜 그런지 생각을 해보면, 처음에 테스트케이스의 수 T를 입력받는 과정에서 개행 문자가 버퍼에 남아있다가 string을 입력받을 때 하나의 줄로 인식되어 오류를 발생시키는 것이라고 유추해볼 수 있습니다.

따라서 이를 해결하기 위해 ignore 함수를 활용하여 버퍼를 비워주고 처리해보겠습니다.

 

#include <bits/stdc++.h>
using namespace std;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL), cout.tie(NULL);

    int T; cin >> T;
    cin.ignore();

    while(T--) {
        string str; getline(cin, str);

        if(str[0] >= 'a' && str[0] <= 'z')
            str[0] = char(str[0] + 'A' - 'a');

        cout << str << "\n";
    }
}

 

위의 코드는 정답 처리를 받은 풀이 코드입니다.

 

처음에 T를 입력받고, 그 다음 cin.ignore를 사용하여 버퍼를 비워줌을 확인할 수 있습니다.

 

그리고 나서는 일반적으로 풀이해주면 됩니다.

각 줄에 대해서 getline(cin, str)로 입력을 받으면 공백을 포함하여 개행 문자가 나오기 전까지 줄 단위로 입력을 받을 수 있습니다.

 

 

 

 

 

반응형