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

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

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

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

19.07.2014, 15:40. Просмотров 538. Ответов 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);
    }
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.07.2014, 15:40     Программа "калькулятор" через процедурное программирование
Посмотрите здесь:

C++ чем отличается вызов объекта через "." и через "->"
Олимпиадное задание "Калькулятор рациональных дробей" C++
Необработанное исключение в "0x00414558" в "467.exe": 0xC0000005: Нарушение прав доступа при чтении "0xabababbb" C++
C++ Что означает "Программа "[4872] laba!.exe: Машинный код" завершилась с кодом 3 (0x3)."?
что дальше? (программа вводит информацию из ведомости и печатает фамилии студентов, учащихся на "4". "5" и их процентное соотношение с другими) C++
Программа "Аэрофлот", тема "Структура" C++
C++ Через ООП: Дать для числа наименование: "рубль", "рубля", "рублей";
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
rikimaru2013
C++ Game Dev
2376 / 1070 / 234
Регистрация: 30.11.2013
Сообщений: 3,551
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;
 
    
 
}
Spiderman5
31 / 31 / 14
Регистрация: 07.04.2014
Сообщений: 219
19.07.2014, 17:21  [ТС]     Программа "калькулятор" через процедурное программирование #3
Спасибо ! А вы могли бы закомментировать эти 4-5 строк,
потому что мы таким образом никогда не писали (
Alex5
1030 / 693 / 102
Регистрация: 12.04.2010
Сообщений: 1,750
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".
Spiderman5
31 / 31 / 14
Регистрация: 07.04.2014
Сообщений: 219
19.07.2014, 22:17  [ТС]     Программа "калькулятор" через процедурное программирование #5
Пробелы нужно все исключать.
Пробел не является каким-либо знаком операции.
Alex5
1030 / 693 / 102
Регистрация: 12.04.2010
Сообщений: 1,750
20.07.2014, 12:17     Программа "калькулятор" через процедурное программирование #6
Цитата Сообщение от Spiderman5 Посмотреть сообщение
Пробелы нужно все исключать.
Строка: " 5 6 + 4 ".
После исключения пробелов получим строку, не эквивалентную исходной. "56+4".
В исходной строке ошибка, а после исключения пробелов будет напечатано: Ответ: 60.
Spiderman5
31 / 31 / 14
Регистрация: 07.04.2014
Сообщений: 219
20.07.2014, 13:31  [ТС]     Программа "калькулятор" через процедурное программирование #7
А что такое "5 6" ??? Если вы имеете в виду десятичную дробь, то в калькуляторе она вводится так: "5.6"
А если человек введет: "5 6 - 10", то это будет эквивалентно "56-10".
soon
2537 / 1302 / 81
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
20.07.2014, 13:36     Программа "калькулятор" через процедурное программирование #8
Цитата Сообщение от Spiderman5 Посмотреть сообщение
А если человек введет: "5 6 - 10", то это будет эквивалентно "56-10".
А если он просто опечатался, и между 5 и 6 должен быть знак операции?

Если программу пишете для себя - делайте как знаете. Если для кого-то, то лучше уточнить, чтобы потом не переделывать.
Spiderman5
31 / 31 / 14
Регистрация: 07.04.2014
Сообщений: 219
20.07.2014, 23:04  [ТС]     Программа "калькулятор" через процедурное программирование #9
Ну вот я и говорю, что пробелы должны будут пропускаться.
Я пытался реализовать это, но у меня не вышло (
Jewbacabra
Эксперт PHP
2111 / 1775 / 654
Регистрация: 24.04.2014
Сообщений: 5,086
21.07.2014, 00:00     Программа "калькулятор" через процедурное программирование #10
Цитата Сообщение от Spiderman5 Посмотреть сообщение
Ну вот я и говорю, что пробелы должны будут пропускаться.
Каким образом можно вывести массив символов из функции
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.07.2014, 22:44     Программа "калькулятор" через процедурное программирование
Еще ссылки по теме:

Как сделать, так чтобы i и j можно было вводить самому "i" И "j" в цикле, есть программа C++
Как через "IF" сделать чтобы программа закрывалась после ввода неверного значения C++
C++ Иерархия классов "список"-"очередь", вызов метода через класс интерфейс
C++ Не могу найти ошибку "Простейший калькулятор"
C++ Что такое "эхо печать"? И как через такую печать сделать калькулятор?

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

Или воспользуйтесь поиском по форуму:
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);
    }
}
Yandex
Объявления
21.07.2014, 22:44     Программа "калькулятор" через процедурное программирование
Ответ Создать тему
Опции темы

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