В вашем классе стека есть разные проблемы, уже отмеченные в комментариях. После исправления этих ошибок в основной программе осталось всего несколько ошибок.
Я использовал std::unique_ptr<>
в вашем массиве вместо необработанного указателя и отключил семантику перемещения, поэтому он не может быть скопирован (из-за unique_ptr
) ни подвижный.
Я также добавил исключения исключения, если вы пытаетесь получить доступ к стеку за пределами.
#include <cctype>
#include <cstddef>
#include <exception>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <utility>
template<typename T>
class aStack {
public:
using value_type = T;
explicit aStack(size_t c) :
cap(c), stored(0), stack(std::make_unique<value_type[]>(cap)) {}
aStack(aStack&&) = delete; // moving disabled
void reset() noexcept { stored = 0; }
void push(const value_type& v) {
if(stored == cap) throw std::runtime_error("stack is full");
stack[stored++] = v;
}
void push(value_type&& v) {
if(stored == cap) throw std::runtime_error("stack is full");
stack[stored++] = std::move(v);
}
value_type& pop() {
if(stored == 0) throw std::runtime_error("stack is empty");
return stack[--stored];
}
[[nodiscard]] const value_type& top() const {
if(stored == 0) throw std::runtime_error("stack is empty");
return stack[stored - 1];
}
[[nodiscard]] value_type& top() {
if(stored == 0) throw std::runtime_error("stack is empty");
return stack[stored - 1];
}
[[nodiscard]] size_t capability() const noexcept { return cap; }
[[nodiscard]] size_t size() const noexcept { return stored; }
private:
size_t cap, stored;
std::unique_ptr<value_type[]> stack;
};
Когда дело доходит до основной программы, основной проблемой было то, что вы забыл преобразовать значение ASCII каждого di git в целое число. Другой проблемой был расчет op
. Вы сохранили значение из последней итерации вместо того, чтобы получить новое значение из стека. Было также дополнительное выделение памяти, которое было ненужным, поэтому я удалил его. У вас также были shadowing переменные, которые не вызывали ошибок, но затрудняли чтение кода.
int main(int argc, char* argv[]) {
if(argc < 2) {
std::cout << "USAGE: " << argv[0] << " <equation>\n";
return 1;
}
std::string equation(argv[1]);
try {
int op, result;
aStack<int> stack(equation.length());
for(size_t ei = 0; ei < equation.length(); ++ei) {
if(std::isdigit(equation[ei])) {
stack.push(equation[ei] - '0'); // from ASCII to digit
} else {
op = stack.pop(); // start with what's on the stack
switch(equation[ei]) {
case '+':
while(stack.size()) {
op += stack.pop();
}
stack.push(op);
break;
case '-':
while(stack.size()) {
op -= stack.pop();
}
stack.push(op);
break;
case '*':
while(stack.size()) {
op *= stack.pop();
}
stack.push(op);
break;
case '/':
while(stack.size()) {
op /= stack.pop();
}
stack.push(op);
break;
default:
throw std::runtime_error("invalid operation");
}
}
}
result = stack.pop();
if(stack.size() != 0)
throw std::runtime_error("stack not empty when calculation ended");
std::cout << result << '\n';
} catch(const std::exception& ex) {
std::cerr << "Exception: " << ex.what() << '\n';
}
}