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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 5.00
StelSvip
0 / 0 / 0
Регистрация: 10.02.2014
Сообщений: 24
#1

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

10.02.2014, 19:59. Просмотров 1411. Ответов 8
Метки нет (Все метки)

Здравствуйте, нужна помощь в создании калькулятора. Калькулятор должен работать при вводе например: 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;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.02.2014, 19:59
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Калькулятор на C++ (C++):

Простой калькулятор и калькулятор с парсингом - C++
Ребят я совсем не давно только начал изучать сишку, решил написать простенький калькулятор который работает с 2 числами. Возник вопрос, как...

Калькулятор - C++
Доброго времени суток, Народ! Помогите плиз с задачей. Нужен исходник калькулятора, самого простого, на 4 действия. Заранее спасибо!!!

Калькулятор на С++ - C++
Сделал калькулятор, работает нормально, но программа считает только два числа за раз: &gt;&gt;Картинка&lt;&lt; , как сделать так чтоб пользователь...

Калькулятор на C++ - C++
Приветствую всех. Ребят нужна помощь, в с++ особо то не рублю, веб-разработкой занимаюсь, а дали задание. Может у кого есть подобное &quot;чудо&quot;...

Калькулятор - C++
Пишу калькулятор. Прошу помощи. Вот мой код #include &lt;iostream&gt; #include &lt;locale.h&gt; #include &lt;string.h&gt; #include &lt;cmath&gt; using...

Калькулятор - C++
Помогите пожалуйста сделать в этом калькуляторе скобки. #include &lt;iostream&gt; #include &lt;stdlib.h&gt; #include &lt;string.h&gt; #include...

8
ТОрчОК
Заблокирован
10.02.2014, 21:54 #2
Бьерн Страуструп Язык программирования C++
там есть в начале какой-то главы тема калькулятор. все подробно описано
1
StelSvip
0 / 0 / 0
Регистрация: 10.02.2014
Сообщений: 24
11.02.2014, 09:51  [ТС] #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;
}
0
Fene4ka_
91 / 91 / 16
Регистрация: 24.01.2014
Сообщений: 1,215
11.02.2014, 11:32 #4
StelSvip, как-то выражение -2+2*3-4/2 он не правильно посчитал
1
egor2116
340 / 371 / 42
Регистрация: 20.01.2013
Сообщений: 1,130
11.02.2014, 11:48 #5
Бьерн Страуструп Язык программирования C++
Почитаю книгу на днях
интересно
0
StelSvip
0 / 0 / 0
Регистрация: 10.02.2014
Сообщений: 24
11.02.2014, 15:24  [ТС] #6
Цитата Сообщение от Fene4ka_ Посмотреть сообщение
StelSvip, как-то выражение -2+2*3-4/2 он не правильно посчитал
хммм... действительно.

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

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

Калькулятор - C++
Решил написать калькулятор, а вот и он: #include&lt;conio.h&gt; #include&lt;locale.h&gt; #include&lt;stdio.h&gt; #define END '0' #define ERROR 'a' ...

Калькулятор - C++
Вот сам калькулятор: #include&lt;conio.h&gt; #include&lt;locale.h&gt; #include&lt;stdio.h&gt; #define END '0' #define ERROR -1 #include&lt;stdlib.h&gt;...

Калькулятор - C++
Написал примитивный калькулятор: #include &lt;iostream&gt; #include &lt;locale.h&gt; #include &lt;conio.h&gt; using namespace std; int...

Калькулятор - C++
Есть такое условие: If(b=='+') s=a+b; как сделать так чтобы я мог додавать не два числа а a+b+...+n


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru