Форум программистов, компьютерный форум CyberForum.ru

Калькулятор на C++ - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 5.00
StelSvip
0 / 0 / 0
Регистрация: 10.02.2014
Сообщений: 24
10.02.2014, 19:59     Калькулятор на C++ #1
Здравствуйте, нужна помощь в создании калькулятора. Калькулятор должен работать при вводе например: 5+3*2.
И соответственно должен выдать результат, равный 11. Сам даже не знаю с чего начать, знаю что примерно надо стеком. Хотел по-готовому методом тыка - понять, как все это происходит. Нашел пример на хабре, но там очень большой код, и еще используются скобки, в моем случае они не нужны. Код привел ниже под споилером. И так же там множество проверок на ввод корректных данных, которые мне так же не нужны.
Заранее спасибо, всем кто откликнется.
Код найденный на хабре
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <string>
#include <vector>
#include <stdexcept>
 
struct token {
    enum { E_UNDEF, E_NUMBER, E_OPERATOR, E_LEVEL  } type;
 
    union {
        double d_val;
        int i_val;
        char c_val;
    } data;
 
    token() {
        type = E_UNDEF;
    }
 
    token(double val) : type(E_NUMBER) {
        data.d_val = val;
    }
    token(int val) : type(E_LEVEL) {
        data.i_val = val;
    }
    token(char val) : type(E_OPERATOR) {
        data.c_val = val;
    }
};
 
typedef std::vector<token> tokens;
 
void push_level(tokens &pr, int level) {
    if (pr.empty() || pr.back().type != token::E_LEVEL) {
        pr.push_back(token(level));
    } else {
        pr.back().data.i_val += level;
    }
}
 
void push_operator(tokens &pr, char op) {
    pr.push_back(token(op));
}
 
void push_number(tokens &pr, int num) {
    if (pr.empty() || pr.back().type == token::E_LEVEL || (pr.back().type == token::E_OPERATOR && pr.size() > 1 && pr[pr.size() - 2].type == token::E_NUMBER) ) {
        pr.push_back(token((double)num));
    } else if (pr.back().type == token::E_OPERATOR && (pr.size() == 1 || pr[pr.size() - 2].type == token::E_LEVEL) ) {
        if (pr.back().data.c_val == '*' || pr.back().data.c_val == '/') {
            throw std::domain_error("unexpected operator");
        }
        if (pr.back().data.c_val == '-') {
            num = -num;
        }
        pr.pop_back();
        pr.push_back(token((double)num));
    } else {
        throw std::domain_error("unexpected number");
    }
}
 
token calc3(tokens &pr) {
    token s2 = pr.back(); pr.pop_back();
    token op = pr.back(); pr.pop_back();
    token s1 = pr.back(); pr.pop_back();
 
    if (s1.type != token::E_NUMBER || op.type != token::E_OPERATOR || s2.type != token::E_NUMBER) {
        throw std::domain_error("unexpected closing brace");
    }
 
    switch (op.data.c_val) {
        case '+':
            s1.data.d_val += s2.data.d_val;
            break;
        case '-':
            s1.data.d_val -= s2.data.d_val;
            break;
        case '*':
            s1.data.d_val *= s2.data.d_val;
            break;
        case '/':
            s1.data.d_val /= s2.data.d_val;
            break;
        default:
        throw std::domain_error("internal error");
    }
 
    return s1;
}
 
void pop_level(tokens &pr, int level) {
    if (level == 0) {
        if (pr.size() > 3) {
            pr.push_back(calc3(pr));
        }
        return;
    }
    if (pr.empty() || pr.back().type == token::E_LEVEL || pr.back().type == token::E_OPERATOR) {
        throw std::domain_error("unexpected closing brace");
    } else if (pr.size() > 1 && pr[pr.size() - 2].type == token::E_LEVEL) {
        if (pr[pr.size() - 2].data.i_val > level) {
            pr[pr.size() - 2].data.i_val -= level;
        } else {
            int delta = level - pr[pr.size() - 2].data.i_val;
            token tmp = pr.back();
            pr.pop_back(); pr.pop_back();
            pr.push_back(tmp);
            pop_level(pr, delta);
        }
    } else if (pr.size() > 3) {
        token s1 = calc3(pr);
 
        if (pr.back().type == token::E_LEVEL) {
            if (pr.back().data.i_val > level) {
                pr.back().data.i_val -= level;
                pr.push_back(s1);
            } else {
                int delta = level - pr.back().data.i_val;
                pr.pop_back();
                pr.push_back(s1);
                pop_level(pr, delta);
            }
        } else if (pr.back().type == token::E_OPERATOR) {
            pr.push_back(s1);
            pop_level(pr, level);
        } else {
            throw std::domain_error("unexpected closing brace");
        }
    } else {
        throw std::domain_error("unexpected closing brace");
    }
}
 
double process(const std::string &str) {
    tokens program;
 
    push_level(program, 3);
    for (std::string::const_iterator cit = str.begin(); cit != str.end(); ++cit) {
        switch (*cit) {
            case '(':
                push_level(program, 3);
                break;
            case ')':
                pop_level(program, 3);
                break;
            case '*':
            case '/':
                pop_level(program, 1);
                push_operator(program, *cit);
                push_level(program, 1);
                break;
            case '+':
            case '-':
                if (cit == str.begin() || strchr("(+/-*", *(cit-1))) {
                    push_operator(program, *cit);
                } else {
                    pop_level(program, 2);
                    push_operator(program, *cit);
                    push_level(program, 2);
                }
                break;
            case ' ':
                break;
            case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
                {
                    int curnum = 0;
                    while (cit != str.end()) {
                        curnum = 10*curnum + (*cit - '0');
                        if ((cit + 1) == str.end() || !isdigit(*(cit+1))) {
                            break;
                        }
                        ++cit;
                    }
                    push_number(program, curnum);
                }
                break;
            default:
                throw std::domain_error("unexpected symbol");
        }
    }
    pop_level(program, 3);
 
    if (program.size() == 0 || program.size() > 1) {
        throw std::domain_error("incomplete expression");
    }
 
    return program.back().data.d_val;
}
 
int main() {
    std::string line;
    while (!std::cin.eof()) {
        std::getline(std::cin, line);
 
        if (line.length() > 0) {
            try {
                std::cout << process(line) << std::endl;
            } catch (std::exception &e) {
                std::cout << "error: " << e.what() << std::endl;
            }
        }
    }
 
    return 0;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.02.2014, 19:59     Калькулятор на C++
Посмотрите здесь:

Калькулятор на С++ C++
C++ Калькулятор на С
C++ Калькулятор
Калькулятор C++
Калькулятор C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ТОрчОК
Заблокирован
10.02.2014, 21:54     Калькулятор на C++ #2
Бьерн Страуструп Язык программирования C++
там есть в начале какой-то главы тема калькулятор. все подробно описано
StelSvip
0 / 0 / 0
Регистрация: 10.02.2014
Сообщений: 24
11.02.2014, 09:51  [ТС]     Калькулятор на C++ #3
Да, действительно. Спасибо. Некоторые вещи из программы мне еще не понятны. Почитаю книгу на днях, попробую разобраться. Еще раз спасибо.

Добавлено через 4 часа 45 минут
Сделал по-другому. По уроку. Кому понадобится код ниже. Позже попробую со скобками сделать.
код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <iostream>
using namespace std;
 
float number()
{
    int num = 0;
    for(;;)
    {
        char c = cin.get();
        if(c >= '0' && c <= '9')
        {
            num = num * 10 + c - '0';
        }
        else 
        {
            cin.putback(c);
            break;
        }
    }
    return num;
}
float pr1()
{
    float x = number();
    char c = cin.get();
    switch (c)
    {
    case '*':
        return x * pr1();
    case '/':
        return x / pr1();
    default:
        cin.putback(c);
        return x;
    }
}
 
float pr2()
{
    float x = pr1();
    char c = cin.get();
    switch (c)
    {
    case '+':
        return x + pr2();
    case '-': 
        return x - pr2();
    default: 
        cin.putback(c);
        return x;
    }
}
 
int main()
{
    setlocale(LC_ALL, "");
    cout << "Введите выражение: ";
    float r = pr2 ();
    cout << "Результат: " << r << endl;
    system("pause");
    return 0;
}
Fene4ka_
84 / 84 / 16
Регистрация: 24.01.2014
Сообщений: 1,142
11.02.2014, 11:32     Калькулятор на C++ #4
StelSvip, как-то выражение -2+2*3-4/2 он не правильно посчитал
egor2116
 Аватар для egor2116
337 / 368 / 42
Регистрация: 20.01.2013
Сообщений: 1,100
11.02.2014, 11:48     Калькулятор на C++ #5
Бьерн Страуструп Язык программирования C++
Почитаю книгу на днях
интересно
StelSvip
0 / 0 / 0
Регистрация: 10.02.2014
Сообщений: 24
11.02.2014, 15:24  [ТС]     Калькулятор на C++ #6
Цитата Сообщение от Fene4ka_ Посмотреть сообщение
StelSvip, как-то выражение -2+2*3-4/2 он не правильно посчитал
хммм... действительно.

Добавлено через 2 минуты
Не пойму только почему. Как вариант не видит -2 в самом начале. Но тогда ведь при вводе 0-2+2*3-4/2 должен правильно считать, но не считает.

Добавлено через 2 минуты
Таак. При вводе даже -5+2, ответ дает -7. Т.е по порядку действие. сначала увидел минус. и посчита 5 - 2. а потом только +. но чисел не осталось.
Fene4ka_
84 / 84 / 16
Регистрация: 24.01.2014
Сообщений: 1,142
11.02.2014, 15:37     Калькулятор на C++ #7
StelSvip, просто этот минус не обрабатывается, а потом выводится ...
StelSvip
0 / 0 / 0
Регистрация: 10.02.2014
Сообщений: 24
11.02.2014, 15:45  [ТС]     Калькулятор на C++ #8
Цитата Сообщение от Fene4ka_ Посмотреть сообщение
StelSvip, просто этот минус не обрабатывается, а потом выводится ...
Ааа.. точно. А как исправить? не поможете?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.02.2014, 19:14     Калькулятор на C++
Еще ссылки по теме:

Калькулятор C++
Калькулятор C++
Простой калькулятор и калькулятор с парсингом C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Fene4ka_
84 / 84 / 16
Регистрация: 24.01.2014
Сообщений: 1,142
11.02.2014, 19:14     Калькулятор на C++ #9
StelSvip, вы все делаете с переменной, попробуйте сделать структуру, которая будет хранить числа и знаки, а в последствии их обрабатывать ...
Yandex
Объявления
11.02.2014, 19:14     Калькулятор на C++
Ответ Создать тему
Опции темы

Текущее время: 02:31. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru