Programming 기초/Coding Test

[bj 8958] c++, cin 다음에 cin.getline 사용할 시 cin.ignore() 해주기

코딩상륙작전 2024. 7. 19. 16:29

https://www.acmicpc.net/problem/8958

 

동적할당을 이용한 문자열을 연습하기 위해 아래와 같이 코드를 짜보았다.

#include <iostream>
using namespace std;

int main(int argc, char **argv)
{
    int n;
    cin >> n;
    cin.ignore();
    for (int i = 0; i < n; ++i)
    {
        char *s = new char[81];
        cin.getline(s, 81);

        int cnt = 0;
        int ret = 0;
        for (int i = 0; i < 81; ++i)
        {
            if (s[i] == '\0')
                break;
            if (s[i] == 'O')
            {
                ++cnt;
                ret += cnt;
            }
            else
            {
                cnt = 0;
            }
        }
        cout << ret << "\n";
        delete[] s;
    }
    return 0;
}

 

주의해야 할 점

  • cin은 버퍼에 '\n'이 남아있어서 cin.getline() 하기 전에 cin.ignore()로 버퍼를 비워주지 않으면 cin 직후의 cin.getline에 '\n'이 입력되어버린다.
  • 처음에는 아무생각없이 cin.getline 직전에 cin.ignore()를 적용했으나, cin.ignore()는 디폴트값이 버퍼의 1개를 지우는 것이므로 cin.getline()에서의 입력값의 첫 번째 글자가 지워지게 되어 논리적 오류가 발생했다. 꼭 처음 n을 받는 cin 다음에 cin.ignore()를 적용해주자.
  • ignore 함수의 디폴트 값을 기억하기 쉽게 cin.ignore(1)로 습관화하는 것이 좋을 듯 싶다. 
  • cin.getline은 문자열 입력 마지막에 '\0'을 추가한다. 남은 메모리 공간에 대해서는 초기화하지 않아서 garbage 값이 들어가 있다.

 

string을 활용한 풀이

#include <iostream>
#include <string>
using namespace std;

int main(int argc, char argv)
{
    int n;

    cin >> n;
    cin.ignore(1);

    for (int i = 0; i < n; ++i)
    {
        string str;
        getline(cin, str);

        int ret = 0;
        int cnt = 0;
        for (auto s : str)
        {
            if (s == 'O')
            {
                ++cnt;
                ret += cnt;
            }
            else
                cnt = 0;
        }
        cout << ret << '\n';
    }
    return 0;
}