Smart Calculator C++

👤 Sharing: AI
```cpp
#include <iostream>
#include <string>
#include <stack>
#include <queue>
#include <map>
#include <algorithm>
#include <sstream>
#include <cmath>

using namespace std;

// Function to check if a character is a digit
bool isDigit(char c) {
    return (c >= '0' && c <= '9');
}

// Function to check if a character is an operator
bool isOperator(char c) {
    return (c == '+' || c == '-' || c == '*' || c == '/' || c == '^');
}

// Function to get the precedence of an operator
int getPrecedence(char op) {
    if (op == '^') return 3;
    if (op == '*' || op == '/') return 2;
    if (op == '+' || op == '-') return 1;
    return 0;
}

// Function to convert infix expression to postfix expression
string infixToPostfix(const string& infix) {
    string postfix = "";
    stack<char> operators;

    for (char c : infix) {
        if (isspace(c)) continue; // Ignore whitespace

        if (isDigit(c)) {
            postfix += c;
        } else if (isOperator(c)) {
            while (!operators.empty() && operators.top() != '(' && getPrecedence(c) <= getPrecedence(operators.top())) {
                postfix += operators.top();
                operators.pop();
            }
            operators.push(c);
        } else if (c == '(') {
            operators.push(c);
        } else if (c == ')') {
            while (!operators.empty() && operators.top() != '(') {
                postfix += operators.top();
                operators.pop();
            }
            operators.pop(); // Remove the '('
        }
    }

    while (!operators.empty()) {
        postfix += operators.top();
        operators.pop();
    }

    return postfix;
}

// Function to evaluate a postfix expression
double evaluatePostfix(const string& postfix) {
    stack<double> operands;

    for (char c : postfix) {
        if (isDigit(c)) {
            operands.push(c - '0'); // Convert char to double
        } else if (isOperator(c)) {
            if (operands.size() < 2) {
                cerr << "Error: Not enough operands for operator " << c << endl;
                return NAN; // Not a Number
            }

            double operand2 = operands.top();
            operands.pop();
            double operand1 = operands.top();
            operands.pop();

            double result;
            switch (c) {
                case '+': result = operand1 + operand2; break;
                case '-': result = operand1 - operand2; break;
                case '*': result = operand1 * operand2; break;
                case '/':
                    if (operand2 == 0) {
                        cerr << "Error: Division by zero!" << endl;
                        return NAN;
                    }
                    result = operand1 / operand2;
                    break;
                case '^': result = pow(operand1, operand2); break;
                default:
                    cerr << "Error: Invalid operator " << c << endl;
                    return NAN;
            }

            operands.push(result);
        }
    }

    if (operands.size() == 1) {
        return operands.top();
    } else {
        cerr << "Error: Invalid postfix expression" << endl;
        return NAN;
    }
}


// Function to handle variables
map<string, double> variables;

double evaluateExpression(const string& expression) {
    string cleanedExpression = "";
    string currentToken = "";

    for (char c : expression) {
        if (isalnum(c)) {
            currentToken += c;
        } else {
            if (!currentToken.empty()) {
                if (variables.count(currentToken)) {
                    cleanedExpression += to_string(variables[currentToken]);
                } else {
                    cleanedExpression += currentToken;
                }
                currentToken = "";
            }
            cleanedExpression += c;
        }
    }

    if (!currentToken.empty()) {
        if (variables.count(currentToken)) {
            cleanedExpression += to_string(variables[currentToken]);
        } else {
            cleanedExpression += currentToken;
        }
    }

    string postfixExpression = infixToPostfix(cleanedExpression);
    return evaluatePostfix(postfixExpression);
}


int main() {
    string input;

    while (true) {
        cout << "> ";
        getline(cin, input);

        // Exit condition
        if (input == "/exit") {
            cout << "Bye!" << endl;
            break;
        }

        // Help command
        if (input == "/help") {
            cout << "This is a simple calculator that supports basic arithmetic operations." << endl;
            cout << "You can use +, -, *, /, and ^ (power) operators." << endl;
            cout << "You can also define variables using the assignment operator (=)." << endl;
            cout << "Type /exit to exit the calculator." << endl;
            continue;
        }

        // Variable assignment
        size_t assignmentPos = input.find('=');
        if (assignmentPos != string::npos) {
            string variableName = input.substr(0, assignmentPos);
            string expression = input.substr(assignmentPos + 1);

            // Trim whitespace
            variableName.erase(0, variableName.find_first_not_of(" \t\n\r"));
            variableName.erase(variableName.find_last_not_of(" \t\n\r") + 1);
            expression.erase(0, expression.find_first_not_of(" \t\n\r"));
            expression.erase(expression.find_last_not_of(" \t\n\r") + 1);
            
             if (!isalpha(variableName[0]) || !all_of(variableName.begin(), variableName.end(), [](char c){ return isalnum(c); })) {
                cout << "Invalid identifier" << endl;
                continue;
            }
            

            double value = evaluateExpression(expression);
            if (!isnan(value)) {
                variables[variableName] = value;
            } else {
                cout << "Invalid assignment" << endl;
            }
        }
        // Check if the input is a single variable
        else if (isalpha(input[0]) && all_of(input.begin(), input.end(), [](char c){ return isalnum(c); }))
        {
            if(variables.count(input)){
                cout << variables[input] << endl;
            } else {
                cout << "Unknown variable" << endl;
            }
        }
        // Evaluate expression
        else {
            double result = evaluateExpression(input);
            if (!isnan(result)) {
                cout << result << endl;
            } else {
                // Display error if the expression is invalid.  Other errors are displayed by the evaluation functions.
                bool containsCharacters = false;
                for(char c : input){
                    if(isalpha(c)) {
                        containsCharacters = true;
                        break;
                    }
                }
                if(containsCharacters){
                    
                } else {
                    cout << "Invalid expression" << endl;
                }
            }
        }
    }

    return 0;
}
```
👁️ Viewed: 11

Comments