Problem p00109 (C++) — buggy submission, verdict: Runtime Error

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

int op_priority(char a) {
  if (a == '+' || a == '-')
    return 0;
  if (a == '*' || a == '/')
    return 1;
  return -1;
}

void clac_once(stack<long long> &num_stack, stack<char> &op_stack) {
  long long a, b;
  long long c;
  char op;

  b = num_stack.top();
  num_stack.pop();
  a = num_stack.top();
  num_stack.pop();
  op = op_stack.top();
  op_stack.pop();

  switch (op) {
  case '+':
    c = a + b;
    break;
  case '-':
    c = a - b;
    break;
  case '*':
    c = a * b;
    break;
  case '/':
    c = a / b;
  }

  num_stack.push(c);
}

long long clac(string str) {
  stack<long long> num_stack;
  stack<char> op_stack;

  for (int i = 0; i < str.size();) {
    if (str[i] == '(') {
      int start = ++i;
      int count = 1;

      while (count) {
        if (str[i] == ')')
          count--;
        else if (str[i] == '(')
          count++;
        i++;
      }

      num_stack.push(clac(string(str.begin() + start, str.begin() + i)));
    } else if (str[i] == '+' || str[i] == '-' || str[i] == '*' ||
               str[i] == '/' || str[i] == '=' || str[i] == ')') {
      while (!op_stack.empty() &&
             op_priority(op_stack.top()) >= op_priority(str[i])) {
        clac_once(num_stack, op_stack);
      }
      op_stack.push(str[i]);
      i++;
    } else if ('0' <= str[i] && str[i] <= '9') {
      long long tmp = 0;
      while ('0' <= str[i] && str[i] <= '9') {
        tmp *= 10;
        tmp += str[i] - '0';
        i++;
      }
      num_stack.push(tmp);
    }
  }

  if (op_stack.size() != 1)
    exit(1);

  return num_stack.top();
}

int main() {
  int n;

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

    cin >> str;
    cout << clac(str) << endl;
  }

  return 0;
}

Error: 0

Fixed submission:

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

int op_priority(char a) {
  if (a == '+' || a == '-')
    return 0;
  if (a == '*')
    return 1;
  if (a == '/')
    return 2;
  return -1;
}

void clac_once(stack<int> &num_stack, stack<char> &op_stack) {
  int a, b;
  int c;
  char op;

  b = num_stack.top();
  num_stack.pop();
  a = num_stack.top();
  num_stack.pop();
  op = op_stack.top();
  op_stack.pop();

  switch (op) {
  case '+':
    c = a + b;
    break;
  case '-':
    c = a - b;
    break;
  case '*':
    c = a * b;
    break;
  case '/':
    c = a / b;
  }

  num_stack.push(c);
}

int clac(string str) {
  stack<int> num_stack;
  stack<char> op_stack;

  for (int i = 0; i < str.size();) {
    if (str[i] == '(') {
      int start = ++i;
      int count = 1;

      while (count) {
        if (str[i] == ')')
          count--;
        else if (str[i] == '(')
          count++;
        i++;
      }

      num_stack.push(clac(string(str.begin() + start, str.begin() + i)));
    } else if (str[i] == '+' || str[i] == '*' || str[i] == '/' ||
               str[i] == '=' || str[i] == ')') {
      while (!op_stack.empty() &&
             op_priority(op_stack.top()) >= op_priority(str[i])) {
        clac_once(num_stack, op_stack);
      }
      op_stack.push(str[i]);
      i++;
    } else if ('0' <= str[i] && str[i] <= '9') {
      int tmp = 0;
      while ('0' <= str[i] && str[i] <= '9') {
        tmp *= 10;
        tmp += str[i] - '0';
        i++;
      }
      num_stack.push(tmp);
    } else if (str[i] == '-') {
      int tmp = 0;
      if (('0' <= str[i - 1] && str[i - 1] <= '9') || !i)
        op_stack.push('+');
      i++;
      while ('0' <= str[i] && str[i] <= '9') {
        tmp *= 10;
        tmp += str[i] - '0';
        i++;
      }
      num_stack.push(tmp * -1);
      while (!op_stack.empty() &&
             op_priority(op_stack.top()) >= op_priority(str[i])) {
        clac_once(num_stack, op_stack);
      }
      op_stack.push(str[i]);
      i++;
    }
  }

  return num_stack.top();
}

int main() {
  int n;

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

    cin >> str;
    cout << clac(str) << endl;
  }

  return 0;
}