본문 바로가기
백준 문제 풀이 & C++ 공부

백준 9012 C++ & cin.ignore()

by daisy0461 2021. 7. 4.

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

 

9012번: 괄호

괄호 문자열(Parenthesis String, PS)은 두 개의 괄호 기호인 ‘(’ 와 ‘)’ 만으로 구성되어 있는 문자열이다. 그 중에서 괄호의 모양이 바르게 구성된 문자열을 올바른 괄호 문자열(Valid PS, VPS)이라고

www.acmicpc.net

이 문제를 풀면서 배운 점은 일단 cin.ignore()에 관해서 배웠습니다.

코드의 제일 밑에 보면 expression string subscript out of range c++이 있는데 이게 제가 처음 코딩을 하고 나서 생긴 오류입니다.

이러한 에러를 처음 만나봐서 해결 방법을 위해 검색을 하였습니다.

그러다가 cin.ignore에 관해서 발견을 하였고 이것을 통해 에러를 해결하였습니다.

 

cin.ignore();

cin은 문자를 입력받는 경우(여기서는 getline) 바로 변수에 저장되는게 아닌 문자가 입력버퍼에 저장되고

버퍼에 저장된 값을 읽어들여 변수에 저장합니다.

 

여기서 버퍼를 모르는 분들을 위해 간단하게 설명을 하자면

버퍼는 데이터를 한 곳에서 다른 곳으로 전달하는 동안

이 예시에서는 입력에서 변수로 저장되는 과정에서 일시적으로 데이터를 저장하는 메모리의 영역입니다.

우리가 대부분 일상적으로 사용하는 버퍼링은 그럼 버퍼를 활용하거나 버퍼를 채우는 방식을 의미합니다.

 

그래서 cin에서 문자를 입력 받을 때는 입력버퍼에 있는 값을 읽어들여 변수에 저장을 하게 되는데

cin을 통해 숫자를 입력받는 경우는 그렇지 않습니다.

숫자는 버퍼를 거치지 않고 바로 변수에 저장됩니다.

 

그럼 이 문제처럼 숫자를 입력받고 문자를 입력받는 cin의 경우에는

string buf;
    int testCase;
    cin >> testCase;
    cin.ignore();

    for (int i = 0; i < testCase; i++) {
        getline(cin, buf);
        stack<char> charstack;

이 문제의 일부에서 발생하는 이러한 경우는 testCase를 입력받은 후에 getline은 입력받지 않고 바로 다음 코드인 stack을 생성합니다.

그 이유는 버퍼에 정수값을 입력한 뒤 누른 '엔터'가 그대로 남아있기 때문에 이 엔터가 getline에 들어가기 때문입니다.

그렇기에 cin.ignore();을 사용합니다.

이걸 사용하게 되면 입력 버퍼의 모든 내용이 제거가 됩니다.숫자를 입력 후 엔터를 치고나면 cin.ignore()에 의해서 엔터가 버퍼에서 제거가되고 getline을 잘 수행을 합니다.

 

#define _CRT_SECURE_NO_WARNINGS

#include<iostream>
#include<string>
#include<string.h>
#include<stack>
using namespace std;

int main()
{
    string buf;
    int testCase;
    cin >> testCase;
    cin.ignore();

    for (int i = 0; i < testCase; i++) {
        getline(cin, buf);
        stack<char> charstack;

        for (int i = 0; i < buf.length(); i++) {
            if (buf[i] == '(') {
                charstack.push('(');
            }
            else if (buf[i] == ')') {
                if (!charstack.empty() && charstack.top() == '(') {
                    charstack.pop();
                }
                else {
                    charstack.push(buf[i]);
                    break;
                }
            }
        }

        if (charstack.empty()) {
            cout << "YES" << endl;
        }
        else {
            cout << "NO" << endl;
        }
    }
}

//expression string subscript out of range c++

 

추가적으로 하나 더 에러가 생긴 사항이 있었는데

expression back() called on empty deque입니다.

이 에러는

if (!charstack.empty() && charstack.top() == '(') {
                    charstack.pop();
                }

여기 이 부분에서 생겼는데 저는 처음에

if (charstack.top() == '(' && !charstack.empty()) {
                    charstack.pop();
                }

이와 같이 작성을 하였습니다. 이렇게 되면 charstack이 empty인 상황이 있을 때 top이랑 비교를 하게 되는데

당연하게도 empty인 상태이면 top은 존재하지 않습니다. 없는 것과 '('와 비교를 하라고 하니 에러가 발생하였습니다.

이렇게 if문에서 무엇을 먼저 비교할지 순서 또한 중요하다는 것을 한번 느끼게 되었습니다. 

'백준 문제 풀이 & C++ 공부' 카테고리의 다른 글

C++ sort & stable_sort  (0) 2021.07.07
C++ Vector Container  (0) 2021.07.05
백준 10773번 C++  (0) 2021.06.22
백준 7568번 C/C++  (0) 2021.06.21
백준 4553번 C/C++  (0) 2021.06.14