Однострочный калькулятор.

Предназначен для выполнения простых вычислений, использующих основные арифметические действия и скобки. Выражение должно быть сохранено в файле “example.txt” в папке программы.

Пример: – 45.5 + 12 * ( -185 – 18 * (6 – 3 )) -217.5

Основная задача программы – обучение приемам работы с контейнером vector и функциями стандартной библиотеки.

Рассмотрим алгоритм программы. На вход программы передается строка текста (std::string) содержащая математическое выражение. Это текст, вычислять пока нечего.

Основные блоки программы:

  • Рекурсивная функция разбора скобок func(). Нам неизвестна глубина вложенности скобок, по этому будем использовать рекурсию.
  • Функция вычисления выражения в скобках parser, с учетом приоритетов выполняемых операций. Умножение и деление выполняются до сложения и вычитания.
// pract_vector.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
//

#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>

using std::cout;
using std::endl;
//*******************************************
void arOut(std::vector<char> ar) {
    for (char c : ar) {
        cout << c;
    }
}
//*******************************************
void arOut(std::vector<float> ar) {
    for (float n : ar) {
        cout << n << endl;
    }
    cout << endl;
}
//*********************************************
float matem(float a, float b, char d) {
    float res{};
    switch (d) {
    case '+':res = a + b; break;
    case '-':res = a - b; break;
    case '*':res = a * b; break;
    case '/':res = a / b; break;
    default: {
        std::cout << endl << "Ошибка в данных.";
        exit(1);
    }
    }
    return res;
}
//*********************************************
std::string calk(std::vector<float> arF, std::vector<char> d) {
    std::string str{};
    float res{};
    int sdv{};
    while (d.size() > 1) {
        if ((d[0] == '*' || d[0] == '/') || (d[1] == '+' || d[1] == '-')) sdv = 0;
        else sdv = 1;
        res = matem(arF[sdv], arF[sdv + 1], d[sdv]);
        arF.erase(arF.begin() + sdv);
        arF[sdv] = res;
        d.erase(d.begin() + sdv);
    }
    res = matem(arF[0], arF[1], d[0]);
    return std::to_string(res);
}
//*********************************************
std::string parser(std::vector<char> ar) {
    std::string str{};
    std::vector<float> arF{};
    std::vector<char> deystv{};
    bool digit = true;
    int arSize = ar.size();
    bool first = true;
    for (int i{}; i < arSize; ++i) {
        if (ar[i] == ' ')continue;
        if (digit) {
            if ((ar[i] >= '0' && ar[i] <= '9') || ar[i] == '.' || ar[i] == ',' || (ar[i] == '-' && first)) {
                str.push_back(ar[i]);
                first = false;
                if (i + 1 < arSize) {
                    if ((isdigit(ar[i + 1]) || ar[i + 1] == '.' || ar[i + 1] == ','))
                        continue;
                }
                arF.push_back(std::stof(str));
                str.clear();
                digit = false;
            }
            else { cout << endl << "Проверьте задание."; exit(1); }
        }
        else {
            if(ar[i] != '\n')
                deystv.push_back(ar[i]);
            digit = true;
            first = true;
        }
    }
    str = calk(arF, deystv);

    return str;
}
//*********************************************
void func(std::vector<char>& ar) {
    std::vector<char>::iterator it = std::find(ar.begin(), ar.end(), '(');
    if (it != ar.end()) {
        std::vector<char> ar1{};
        ar1.insert(ar1.begin(), it+1, ar.end());
        func(ar1);
        std::vector<char>::iterator it1 = std::find(ar1.begin(), ar1.end(), ')');
        if (it1 != ar1.end()) {
            std::vector<char> ar2{};
            ar2.insert(ar2.begin(), ar1.begin(), it1);
            //вычисляем значение в скобках
            std::string str = parser(ar2);
            ar1.erase(ar1.begin(), it1 + 1);
            ar1.insert(ar1.begin(), str.begin(), str.end());
        }
        ar.erase(it, ar.end());
        ar.insert(ar.end(), ar1.begin(), ar1.end());
    } 
}

int main()
{
    setlocale(LC_ALL, "Russian");
    std::ifstream myFile("example.txt", std::ios_base::in);
    std::vector<char> ar{};
    char c;
    if (myFile) {
        while (!myFile.eof()) {
            while ((c = myFile.get()) == ' ');
            if (c == '\n')break;
            if (c != -1) {                  //конец файла?
                ar.push_back(c);
            }
        }
        cout << endl << endl;
        arOut(ar);
        cout << " = ";
        func(ar);
        cout << parser(ar);
    }
    else {
        std::cout << "Hello World!\n";
        cout << "File not found" << endl;
    }

}