예외 오류가 처음보는게 납니다 어떤식으로 고쳐야할까요?
조회수 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 답변
-
해당코드는 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 한것에 대해서 받아주는게 없더라구요...
물론 이거말고 괄호가 열렸는데 안닫히거나 닫힌괄호만 있을 경우에도 에러처리를 할 필요가 있어보입니다.
감사합니다
댓글 입력