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

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

Войти
Регистрация
Восстановить пароль
 
Spiderman5
31 / 31 / 14
Регистрация: 07.04.2014
Сообщений: 219
#1

Программа "калькулятор" через процедурное программирование - C++

19.07.2014, 15:40. Просмотров 553. Ответов 10
Метки нет (Все метки)

Добрый день ! Я написал программу "Калькулятор", в которой можно в строку ввести выражение и будет выдан результат.

У меня только не получается сделать так, чтобы пробелы при вводе не учитывались калькулятором.
Например, если я введу (3+5)*2, то программа выдаст правильный ответ 16.
Если я введу ( 3 + 5 ) * 2, то программа выдаст неправильный ответ.

Я пытался это реализовать - у меня закомментено это в коде, но оно увы не срабатывает (
Кто может подсказать, как решить данную проблему ?

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
#include <iostream>
#include <conio.h>
using namespace std;
 
#define Esc 27
 
double Do_Polynom(const char* polynom, int first, int last);
 
//переводит входящую строку в число с учетом скобок и десятичной точки
double Do_Number(const char* number, int first, int last)
{
    if (number[first] == '(')
        return Do_Polynom(number, first + 1, last - 1);
 
    int length = last - first + 1;
 
    if (!length)
        return 0;
 
    char* temp = new char[length + 1];
 
    for (int i = 0; i < length; i++)
        temp[i] = number[i + first];
 
    temp[length] = '\0';
 
    double result = atof(temp);
 
    delete[] temp;
 
    return result;
}
 
//вычисляет степень - принимает строку и индексы символов, ограничивающие степень
double Do_Power(const char* power, int first, int last)
{
    int i = last;
 
    for (int count = 0; i >= first; i--)
    {
        if (power[i] == ')')
            count++;
 
        else if (power[i] == '(')
            count--;
 
        if (!count && power[i] == '^')
            break;
    }
 
    if (i < first)
        return Do_Number(power, first, last);
 
    double base = Do_Power(power, first, i - 1);
    double exponent = Do_Number(power, i + 1, last);
 
    return pow(base, exponent);
}
 
 
//вычисляет одночлен - принимает строку и индексы символов, ограничивающие нужный одночлен
double Do_Monom(const char* monom, int first, int last)
{
    int i = last;
 
    for (int count = 0; i >= first; i--)
    {
        if (monom[i] == ')')
            count++;
 
        else if (monom[i] == '(')
            count--;
 
        if (!count && (monom[i] == '*' || monom[i] == '/'))
            break;
    }
 
    if (i < first)
        return Do_Power(monom, first, last);
 
    double right = Do_Monom(monom, first, i - 1);
    double left = Do_Power(monom, i + 1, last);
 
    if (monom[i] == '*')
        return right * left;
 
    if (!left)
        cout << "Division by zero is forbidden! Try again more carefully";
    return right / left;
}
 
//вычисляет многочлен - принимает строку и индексы символов, ограничивающие нужный многочлен
double Do_Polynom(const char* polynom, int first, int last)
{
    int i = last;
 
    for (int count = 0; i >= first; i--)
    {
        if (polynom[i] == ')')
            count++;
 
        else if (polynom[i] == '(')
            count--;
 
        if (!count && (polynom[i] == '+' || polynom[i] == '-'))
            break;
    }
 
    if (i < first)
        return Do_Monom(polynom, first, last);
 
    return Do_Polynom(polynom, first, i - 1) + ((polynom[i] == '+') ? 1 : -1) * Do_Monom(polynom, i + 1, last);
}
 
//вычисляет выражение, переданное строкой
double Execute(char* expression) // expression - выражение
{
    int length = strlen(expression);
 
    if (!length)
        return 0;
 
 
    /*for (int i = 0; i < length; i++)
    {
        if (expression[i] == ' ')
        for (int j = i; j < length; j++)
        {
            expression[j] = expression[j + 1];
        }
    }*/
 
    int count = 0;
 
    for (int i = 0; i < length; i++)
    {
        if (expression[i] == '(') // скобка открылась
            count++;
 
        else if (expression[i] == ')') // скобка должна закрыться
            count--;
 
        else if (!(expression[i] == '.' || expression[i] == '+' || expression[i] == '-' || 
            expression[i] == '*' || expression[i] == '/' || expression[i] == ' ' || expression[i] == '^' || expression[i] >= '0' && expression[i] <= '9'))
        {
            cout << "Wrong symbol detected! Try again more carefully";
            return 0;
        }
    }
 
    if (count)
    {// если случилась лишняя скобка
        cout << "Wrong count of brackets!" << endl;
        cout << "Try again more carefully";
 
        return 0;
    }
    
    return Do_Polynom(expression, 0, length - 1);
}
 
void main()
{
    /*cout << "3.5+2*5" << " = " << Execute("3.5+2*5") << endl;                                //  13.5
    cout << "(3+2)*5" << " = " << Execute("(3+2)*5") << endl;                                //  25
    cout << "(3+4*(5-2)-1)/2" << " = " << Execute("(3+4*(5-2)-1)/2") << endl;*/                       //   7
    
    setlocale(LC_ALL, "Russian");
    char s[80]; 
 
    while (true)
    {
        
        cout << "Введите арифметическое выражение:" << endl;
        cin.getline(s, 80);
 
        cout << " = " << Execute(s) << endl;
        
        if (_getch() == Esc)
            exit(0);
    }
}
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.07.2014, 15:40
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Программа "калькулятор" через процедурное программирование (C++):

В зависимости от времени года "весна", "лето", "осень", "зима" определить погоду "тепло", "жарко", "холодно", "очень холодно" - C++
В зависимости от времени года &quot;весна&quot;, &quot;лето&quot;, &quot;осень&quot;, &quot;зима&quot; определить погоду &quot;тепло&quot;, &quot;жарко&quot;, &quot;холодно&quot;, &quot;очень холодно&quot;. Я так...

Через ООП: Дать для числа наименование: "рубль", "рубля", "рублей"; - C++
Помогите пожалуйста с задачей. Могу сделать ее просто, но надо через ООП и у меня не получается. Дано натуральное число N (N&lt;20),...

Что такое "эхо печать"? И как через такую печать сделать калькулятор? - C++
Само задание такое: Создать программу-калькулятор, обеспечивающую ввод с клавиатуры в режиме эхо-печати только цифр, а также...

Где ошибка невозможно преобразовать указатель "this" из "const pers" в "pers &" при выводе объектов через cout - C++
Добрый день! Переписал код из книг Лафоре, создание мультимножества из собственных объектов- справочник телефонный, с именем и фамилией. ...

Реализовать классы "Воин", "Пехотинец", "Винтовка", "Матрос", "Кортик" (наследование) - C++
Разработать программу с использованием наследования классов, реализующую классы: − воин; − пехотинец(винтовка); − матрос(кортик). ...

Как через "IF" сделать чтобы программа закрывалась после ввода неверного значения - C++
Как через &quot;If&quot; Зделать что бы когда ты вводишь не верное значение выполнялося else и консоль закрывалася а не переходило к следующему...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
rikimaru2013
C++ Game Dev
2435 / 1129 / 240
Регистрация: 30.11.2013
Сообщений: 3,686
19.07.2014, 16:07 #2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
 
void main()
{
    setlocale(LC_ALL, "Russian");
 
    string s;
    cout << "Введите арифметическое выражение:" << endl;
    getline(cin, s);
    string::iterator end_pos = remove(s.begin(), s.end(), ' ');
    s.erase(end_pos, s.end());
    cout << s;
 
    
 
}
0
Spiderman5
31 / 31 / 14
Регистрация: 07.04.2014
Сообщений: 219
19.07.2014, 17:21  [ТС] #3
Спасибо ! А вы могли бы закомментировать эти 4-5 строк,
потому что мы таким образом никогда не писали (
0
Alex5
1052 / 715 / 105
Регистрация: 12.04.2010
Сообщений: 1,818
19.07.2014, 18:36 #4
Цитата Сообщение от Spiderman5 Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
double Execute(char* expression) // expression - выражение
{
    int length = strlen(expression);
 
    if (!length)
        return 0;
 
 
    for (int i = 0; i < length; i++)
    {
        if (expression[i] == ' ')
        {
            for (int j = i; j < length; j++)
            {
                expression[j] = expression[j + 1];
            }
        }
    }
    // ...
1) После цикла for() длина строки может отличаться от начальной.
2) См. в отладчике ( или можно добавить cout << " \"" << expression << "\"" << endl; ) не все пробелы будут исключены.
3) Все ли пробелы надо исключать? Пример. "(12 34)*2" (между 12 и 34 пробел вместо знака операции). Исключив пробелы, получим "(1234)*2".
0
Spiderman5
31 / 31 / 14
Регистрация: 07.04.2014
Сообщений: 219
19.07.2014, 22:17  [ТС] #5
Пробелы нужно все исключать.
Пробел не является каким-либо знаком операции.
0
Alex5
1052 / 715 / 105
Регистрация: 12.04.2010
Сообщений: 1,818
20.07.2014, 12:17 #6
Цитата Сообщение от Spiderman5 Посмотреть сообщение
Пробелы нужно все исключать.
Строка: " 5 6 + 4 ".
После исключения пробелов получим строку, не эквивалентную исходной. "56+4".
В исходной строке ошибка, а после исключения пробелов будет напечатано: Ответ: 60.
0
Spiderman5
31 / 31 / 14
Регистрация: 07.04.2014
Сообщений: 219
20.07.2014, 13:31  [ТС] #7
А что такое "5 6" ??? Если вы имеете в виду десятичную дробь, то в калькуляторе она вводится так: "5.6"
А если человек введет: "5 6 - 10", то это будет эквивалентно "56-10".
0
soon
2540 / 1305 / 81
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
20.07.2014, 13:36 #8
Цитата Сообщение от Spiderman5 Посмотреть сообщение
А если человек введет: "5 6 - 10", то это будет эквивалентно "56-10".
А если он просто опечатался, и между 5 и 6 должен быть знак операции?

Если программу пишете для себя - делайте как знаете. Если для кого-то, то лучше уточнить, чтобы потом не переделывать.
0
Spiderman5
31 / 31 / 14
Регистрация: 07.04.2014
Сообщений: 219
20.07.2014, 23:04  [ТС] #9
Ну вот я и говорю, что пробелы должны будут пропускаться.
Я пытался реализовать это, но у меня не вышло (
0
Jewbacabra
Эксперт PHP
2471 / 2059 / 779
Регистрация: 24.04.2014
Сообщений: 6,061
21.07.2014, 00:00 #10
Цитата Сообщение от Spiderman5 Посмотреть сообщение
Ну вот я и говорю, что пробелы должны будут пропускаться.
Каким образом можно вывести массив символов из функции
0
Spiderman5
31 / 31 / 14
Регистрация: 07.04.2014
Сообщений: 219
21.07.2014, 22:44  [ТС] #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
#define _CRT_SECURE_NO_WARNINGS
 
#include <iostream>
#include <conio.h>
using namespace std;
 
#define Esc 27
 
double Do_Polynom(const char* polynom, int first, int last);
 
void Space(char* string)
{
    int i = 0;                          // индекс места в строке "куда копировать"
    int j = 0;                          // индекс места в строке "откуда копировать"
 
    /*while (   (  *(string + i) = *(string + j++)  ) != '\0'   ) // цикл, пока очередной символ не '\0'
    {
        if (*(string + i) != ' ')  // увеличиваем i, если символ не пробел
            i++;
    }
    return;*/
 
    while ((string[i] = string[j++]) != '\0')
    {
        if (string[i] != ' ')
            i++;
    }
    return;
}
 
//переводит входящую строку в число с учетом скобок и десятичной точки
double Do_Number(const char* number, int first, int last)
{
    if (number[first] == '(')
        return Do_Polynom(number, first + 1, last - 1);
 
    int length = last - first + 1;
 
    if (!length) // если длина = 0
        return 0;
 
    char* temp = new char[length + 1];
 
    for (int i = 0; i < length; i++)
        temp[i] = number[i + first];
 
    temp[length] = '\0';
 
    double result = atof(temp);
 
    delete[] temp;
 
    return result;
}
 
//вычисляет степень - принимает строку и индексы символов, ограничивающие степень
double Do_Power(const char* power, int first, int last)
{
    int i = last;
 
    for (int count = 0; i >= first; i--)
    {
        if (power[i] == ')')
            count++;
 
        else if (power[i] == '(')
            count--;
 
        if (!count && power[i] == '^')
            break;
    }
 
    if (i < first)
        return Do_Number(power, first, last);
 
    double base = Do_Power(power, first, i - 1);
    double exponent = Do_Number(power, i + 1, last);
 
    return pow(base, exponent); // функция pow вычисляет base, возведённое в степень exponent
}
 
//вычисляет одночлен - принимает строку и индексы символов, ограничивающие нужный одночлен
double Do_Monom(const char* monom, int first, int last)
{
    int i = last;
 
    for (int count = 0; i >= first; i--)
    {
        if (monom[i] == ')')
            count++;
 
        else if (monom[i] == '(')
            count--;
 
        if (!count && (monom[i] == '*' || monom[i] == '/'))
            break;
    }
 
    if (i < first)
        return Do_Power(monom, first, last);
 
    double right = Do_Monom(monom, first, i - 1);
    double left = Do_Power(monom, i + 1, last);
 
    if (monom[i] == '*')
        return right * left;
 
    if (!left)
        cout << "Division by zero is forbidden! Try again more carefully";
    return right / left;
}
 
//вычисляет многочлен - принимает строку и индексы символов, ограничивающие нужный многочлен
double Do_Polynom(const char* polynom, int first, int last)
{
    int i = last;
 
    for (int count = 0; i >= first; i--)
    {
        if (polynom[i] == ')')
            count++;
 
        else if (polynom[i] == '(')
            count--;
 
        if (!count && (polynom[i] == '+' || polynom[i] == '-'))
            break;
    }
 
    if (i < first)
        return Do_Monom(polynom, first, last);
 
    return Do_Polynom(polynom, first, i - 1) + ((polynom[i] == '+') ? 1 : -1) * Do_Monom(polynom, i + 1, last);
}
 
//вычисляет выражение, переданное строкой
double Execute(char* expression) // expression - выражение
{
    int length = strlen(expression);
 
    if (!length)
        return 0;
 
    int count = 0;
 
    for (int i = 0; i < length; i++)
    {
        if (expression[i] == '(') // скобка открылась
            count++;
 
        else if (expression[i] == ')') // скобка должна закрыться
            count--;
 
        else if (!(expression[i] == '.' || expression[i] == '+' || expression[i] == '-' ||
            expression[i] == '*' || expression[i] == '/' || expression[i] == ' ' || expression[i] == '^' || expression[i] >= '0' && expression[i] <= '9'))
        {
            cout << "Wrong symbol detected! Try again more carefully";
            return 0;
        }
    }
 
    if (count)
    {// если случилась лишняя скобка
        cout << "Wrong count of brackets!" << endl;
        cout << "Try again more carefully";
 
        return 0;
    }
    
    return Do_Polynom(expression, 0, length - 1);
}
 
void main()
{
    /*cout << Execute("(3+5)*6.34-8+9^2/2") << endl;
    cout << "3.5+2*5" << " = " << Execute("3.5+2*5") << endl;                                //  13.5
    cout << "(3+2)*5" << " = " << Execute("(3+2)*5") << endl;                                //  25
    cout << "(3+4*(5-2)-1)/2" << " = " << Execute("(3+4*(5-2)-1)/2") << endl;                        //   7
    cout << "(3+2)/5+(3+4*(5-2)-1)/2" << " = " << Execute("(3+2)/5+(3+4*(5-2)-1)/2") << endl;              //   8
    cout << "16.8/((3+2)/5+(3+4*(5-2)-1)/2)" << " = " << Execute("16.8/((3+2)/5+(3+4*(5-2)-1)/2)") << endl;     //   2.1
    cout << "(64/32)+78-(20/4)+(2*(11-6))+45+2/2" << " = " << Execute("(64/32)+78-(20/4)+(2*(11-6))+45+2/2") << endl;    // 131
    cout << "(3+5)^2-60-2^3" << " = " << Execute("(3+5)^2-60-2^3") << endl;                         //  -4
    cout << "((3+2)/5+(3+4*(5-2)-1)/2)^0.5" << " = " << Execute("((3+2)/5+(3+4*(5-2)-1)/2)^0.5") << endl;        //   2.82843*/
 
    setlocale(LC_ALL, "Russian");
    char s[80] = { 0 };
 
    while (true)
    {       
        cout << "Введите арифметическое выражение:" << endl;
        //cin.getline(s, 80);
        //cin.getline(s, sizeof s);
 
        gets(s);
        Space(s); // удаляем все пробелы из строки
        if (!s[0])
            return;
 
        cout << " = " << Execute(s) << endl;
        
        if (_getch() == Esc)
            exit(0);
    }
}
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.07.2014, 22:44
Привет! Вот еще темы с ответами:

Что означает "Программа "[4872] laba!.exe: Машинный код" завершилась с кодом 3 (0x3)."? - C++
при запуске кода компилятор пишет &quot;Программа &quot; laba!!!!!!.exe: Машинный код&quot; завершилась с кодом 3 (0x3).&quot; и появляется окошечко с ошибкой....

Как сделать, так чтобы i и j можно было вводить самому "i" И "j" в цикле, есть программа - C++
#include &lt;iostream&gt; using namespace std; int main() {int a=0,b=0; int i=0; cout&lt;&lt;&quot;Vvedite i=&quot;&lt;&lt;endl; cin&gt;&gt;i; ...

чем отличается вызов объекта через "." и через "->" - C++
Здравствуйте. Вот создал топик для тех, кто желает сам познать С++, но у которых есть вопросы по базовым знаниям. Начну с вопроса:...

Иерархия классов "список"-"очередь", вызов метода через класс интерфейс - C++
Есть небольшая иерархия классов, контейнер (список) для хранения объектов каждого класса, контейнер (очередь) с указателями на объект...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
21.07.2014, 22:44
Ответ Создать тему
Опции темы

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