예외 오류가 처음보는게 납니다 어떤식으로 고쳐야할까요?

조회수 1495회

중위수식을 받아 후위수식으로 변경후 계산하는 프로그램입니다 0으로 나누는 수가 들어오면 예외라고 가정해서 예외코드를 넣었습니다 코드 오류가 예외 발생(0x75699962, Project4.exe): Microsoft C++ 예외: double, 메모리 위치 0x003DF928. 처리되지 않은 예외 발생(0x75699962, Project4.exe): Microsoft C++ 예외: double, 메모리 위치 0x003DF928. 이렇게 뜹니다. 이럴땐 어떻게 해결을 해야하나요?

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

struct oper {
    int p; // 연산자 우선순위
    string o; // 연산자
};

stack<double> num; // 숫자 스택
stack<oper> op; // 연산자 스택


void calc() {

    double a, b, result;
    b = num.top();
    num.pop();
    a = num.top();
    num.pop();
    string oper = op.top().o;
    op.pop();


    if (oper == "*")
        result = a * b;
    else if (oper == "/")
    {
        result = a / b;
        if (b == 0)throw b;
    }

    else if (oper == "+")
        result = a + b;
    else if (oper == "-")
        result = a - b;


    // 결과 값 스택에 다시 저장
    num.push(result);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    std::cout.tie(NULL);

        string input;
        getline(cin, input);
        stringstream ss(input);

        // 연산자 우선순위에 따라 스택에 push
        // 0 : ( )
        // 1 : + -
        // 2 : * /

        string tok;

        while (ss >> tok) {
            // ( 는 무조건 연산자 스택에 push
            if (tok == "(") {
                op.push({ 0, tok });
            } // ) 가 나오면 ( 가 나올 때 까지 계산
            else if (tok == ")") {
                while (op.top().o != "(")
                    calc();
                op.pop();
            }
            else if (tok == "*" || tok == "/" || tok == "+" || tok == "-") {
                int prior; // 연산자 우선순위
                if (tok == "*")
                    prior = 2;
                else if (tok == "/")
                    prior = 2;
                else if (tok == "+")
                    prior = 1;
                else if (tok == "-")
                    prior = 1;

                // 연산자 우선 순위 낮은게 top으로 올 때까지 계산
                while (!op.empty() && prior <= op.top().p)
                    calc();
                // 스택에 연산자 push
                op.push({ prior, tok });
            }
            else // 숫자일 경우 숫자 스택에 push
                num.push(stod(tok));
        }
        // 남은 연산자 계산
        while (!op.empty())
            calc();

        try {
            calc();
        }
        catch(double &b){
            std::cout << "Error : zero division error";
        }
            std::cout << fixed;
            std::cout.precision(2);
            std::cout << num.top();      
        return 0;   
}

1 답변

  • 좋아요

    0

    싫어요
    채택 취소하기

    해당코드는 g++ 로 컴파일했습니다.

    //생략
    
        if (oper == "*")
            result = a * b;
        else if (oper == "/")
        {
            // 기존에는.. 나눈 후에 b 값 검증 하고 throw b했었음.
            try{
                if ( b == 0 ) {
                    throw b;
                }
                result = a / b;
            }
            catch(double &b) {
                std::cout << "Error : zero division error" << endl;
            }
        }
    
    //생략
    
                    calc();
                    // 스택에 연산자 push
                    op.push({ prior, tok });
                }
                else // 숫자일 경우 숫자 스택에 push
                    num.push(stod(tok));
            }
    
            while (!op.empty()){
                calc();
            }
    
            std::cout << fixed;
            std::cout.precision(2);
            std::cout << num.top();      
            return 0;   
    }
    
    

    cpp 를 잘몰라서 stringstream 에 대해서 잘 몰랐어서... 삽질좀했네요

    확인해보니깐 기존 코드에서는 이미 pop되어있는 스택에 대해서 접근하여 데이터를 갖고오는 와중에 에러가 났었구요... 그러기 때문에 calc() 를 호출하는건 2번이상이면 안될거같습니다(정확히는 빈 스택에 top 호출시 에러발생)

    stack<double> num; // 숫자 스택
    
    int main() {
        double b;
        b = num.top();
    }
    
    // 0x8000a8e <main+20>: movsd  xmm0,QWORD PTR [rax] #num.top();
    

    위와 같은 테스트 코드 짯을때와 동일한 위치에 에러가 발생하더라구요

    그리고 zero division 부분에 대해서는 계산하는 쪽에서 throw 한것에 대해서 받아주는게 없더라구요...

    물론 이거말고 괄호가 열렸는데 안닫히거나 닫힌괄호만 있을 경우에도 에러처리를 할 필요가 있어보입니다.

    감사합니다

    • 답변 감사합니다 덕분에 많은 도움이 되었습니다~! 장현준 2020.9.28 12:33

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)