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

Калькулятор строковый с защитой от дурака - C++

Восстановить пароль Регистрация
Другие темы раздела
C++ Длинная арифметика, деление чисел http://www.cyberforum.ru/cpp-beginners/thread1163286.html
http://www.cyberforum.ru/attachment.php?attachmentid=393890&stc=1&d=1398936287 Помоги с решием , желательно код.Заранее спасибО!
C++ Найти время прилета по времени города прибытия Формат входных данных В первой строке входных данных для программы задано число n < 10000 – количество городов, между которыми осуществляются авиарейсы. Затем в n строках идет описание городов в следующем формате – сначала название города (не содержит пробелов), а затем через пробел – часовой пояс в формате (GMT+<разница во времени> или GMT-<разница во времени>) Затем на вход подается число... http://www.cyberforum.ru/cpp-beginners/thread1163281.html
C++ Чтение файла, лишняя итерация
Вопрос по функции feof(). Я так понимаю она должна сигнализировать о конце файл, если был прочитан последний байт файла. Но у меня в примере снизу это происходит только с одной лишней итерацией (когда последний байта файл считывается, цикл выполняется еще раз и только потом происходит выход из цикла). С чем это связано? void test2() { FILE *f; f =...
C++ Вычислить количество элементов списка, расположенных до заданного значения
Написать функцию, которая вычисляет количество элементов списка, расположенных в списке до заданного значения.
C++ Gets не коректно работает http://www.cyberforum.ru/cpp-beginners/thread1163224.html
gets не коректно работает в следующем коде смысл программы в 2-ух 4 значных строках найти одинаковые символы стоящие в одинаковых порядковых местах #include<iostream> #include<cstdio> using namespace std; int main(void)
C++ Функция, которая вставляет перед каждым отрицательным элементом элемент с нулевым значением Есть двумерный динамический массив (матрица). Нужно написать функцию, которая вставляет перед каждым отрицательным элементом элемент с нулевым значением. подробнее

Показать сообщение отдельно
Rifle
 Аватар для Rifle
25 / 25 / 5
Регистрация: 15.11.2012
Сообщений: 93
Завершенные тесты: 4
01.05.2014, 13:59     Калькулятор строковый с защитой от дурака
На форуме есть возможность выделения кода специальным тегом. В вашем случае это кнопочка "С++", когда вы редактируете сообщение. Выделите код, как полагается, пожалуйста. Мало кто согласится рассматривать ваш пример в подобном виде.
По теме. У меня есть один пример калькулятора, может пригодится. Поддерживает все основные действия, возведение в степень, скобочки, некоторые тригонометрические функции и даже по-моему подсвечивает ошибки.

Кликните здесь для просмотра всего текста
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
207
208
209
210
211
212
213
214
#include <iostream>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cmath>
using std::cin;
using std::cout;
using std::endl;
#include "Windows.h"
 
void eatspaces(char* str); //функция для удаления пробелов
double expr(char* str); //функция, вычисляющая выражение
double term(char* str, int& index); //функция для анализа элемента
double trigon(char* str, int& index); //функция для вычисления тригонометрических значений
double power(char* str, int& index); //функция для извлечения степени
double number(char* str, int& index); //функция, распознающая число
char* extract(char* str, int& index); //функция для извлечения подстроки
 
const int MAX = 80; //максимальный размер буфера
 
int main()
    {
    setlocale(0, "Russian");
    char buffer[MAX] = {0}; //область хранения вычисляемого входного выражения
    cout << endl << "Добро пожаловать в дружественный колькулятор!" << endl
         << "Введите выражение или пустую строку для завершения." << endl;
    for ( ; ; )
        {
        cin.getline(buffer, sizeof buffer); //читаем входную строку
        eatspaces(buffer); //удаляем все пробелы из строки
        if (!buffer[0]) //если пустая строка
            return 0;
        cout << "= " << expr(buffer)
             << endl << endl;
        }
    }
        
void eatspaces(char* str)
    {
    int i = 0;                          //индекс места в строке "куда копировать"
    int j = 0;                          //индекс места в строке "откуда копировать"
    while ((*(str+i) = *(str + j++)) != '\0') //цикл, пока очередной символ не '\0'
        if (*(str+i) != ' ')  //увеличиваем i, если символ не пробел
            i++;
    return;
    }
    
double expr(char* str)
    {
    double value = 0.0;         //здесь сохраняем результат
    int index = 0;              //текущая позиция символа
    value = term(str, index);   //получить первый элемент
    for ( ; ; )                 //бесконечный цикл, выход внутри
        {
        switch (*(str+index++)) //выбрать действие на основе текущего символа
            {
            case '\0':          //конец строки, возвращаем значение
                return value;
            case '+':           //знак плюс, прибавляем элемент к value
                value += term(str, index);
                break;
            case '-':           //знак минус, вычитаем элемент из value
                value -= term(str, index);
                break;
            default:            //все остальное не котируется
                int i = index;
                while (--i > 0)
                    cout << " ";
                cout << "^" << endl;
                cout << "Эй, повнимательней можно?! Здесь обнаружена ошибка. " << endl;
                exit(1);
            }
        }
    }
    
double term(char* str, int& index)
    {
    double value = 0.0;             //здесь накапливается значение результата
    value = power(str, index);      //получить первое число элемента
    //выполняем цикл до тех пор, пока имеем допустимую операцию
    while ((*(str + index) == '*') || (*(str + index) == '/')) 
        {
        if (*(str+index) == '*')
            value *= power(str, ++index);
        if (*(str+index) == '/')
            value /= power(str, ++index);
        }
    return value;
    }
    
    
double power(char* str, int& index)
    {
    double value = 0.0;
    value = trigon(str, index);
    while (*(str + index) == '^')
        {
        value = pow(value, trigon(str, ++index)); //возводим в степень
        }
    return value;
    }   
 
double trigon(char* str, int& index)
    {
    int buf_index = 0;
    int temp_index = index; //переменная для хранения индекса (чтобы если что вернуть индекс без изменений)
    char* p_str = 0;    //временный указатель для сравнения символов
    double value = 0;
    while (isalpha(*(str + temp_index)))
        {
        buf_index++;    //сколько букв
        temp_index++;   //текущий индекс
        }
    if (!buf_index)     //если нет ни одной буквы, то возвращаем число
        {
        value = number(str, index);
        return value;
        }
    else                //иначе смотрим, являются ли буквы чем-нибудь этим
        {
        p_str = new char[buf_index+1];  //а для этого создаем временную строку, чтобы сравнить
        p_str[buf_index] = '\0';
        strncpy(p_str, str+index, buf_index);
        }
    if (strcmp(p_str, "sin") == 0)      //синус в градусах
        {
        value = sin(3.141592/180*number(str, temp_index));
        index = temp_index;
        delete[] p_str;     //не забываем удалить временную строку
        return value;
        }
    else if (strcmp(p_str, "cos") == 0) //косинус в градусах
        {
        value = cos(3.141592/180*number(str, temp_index));
        index = temp_index;
        delete[] p_str;     //не забываем удалить временную строку
        return value;
        }
    else if (strcmp(p_str, "tan") == 0) //тангенс в градусах
        {
        value = tan(3.141592/180*number(str, temp_index));
        index = temp_index;
        delete[] p_str;     //не забываем удалить временную строку
        return value;
        }
    else
        {
        return value;
        }
    }
    
double number(char* str, int& index)
    {
    double value = 0.0;                 //хранит результирующее значение
    if (*(str + index) == '(')
        {
        char* p_substr = 0;
        p_substr = extract(str, ++index);
        value = expr(p_substr);
        delete[] p_substr;
        return value;
        }
    //продуманский цикл, превращает символы в число
    while (isdigit(*(str+index)))       //цикл накапливает ведущие цифры 
        value = 10*value + (*(str + index++) - '0');
    if (*(str + index) != '.')          //если не цифра, проверяем на десятичную точку
        return value;
    double factor = 1.0;                //множитель для десятичных разрядов
    //еще один продуманский цикл, возвращает десятичную часть
    while (isdigit(*(str + (++index)))) //выполнять цикл, пока идут цифры 
        {
        factor *= 0.1;
        value = value + (*(str + index) - '0')* factor;
        }
    return value;
    }
    
char* extract(char* str, int& index)
    {
    char buffer[MAX];       //временное пространство для подстроки
    char* p_str = 0;        //указатель на новую строку для возврата
    int numL = 0;           //счетчик найденных левых скобок
    int buf_index = index;  //сохранить начальное значение index
    do
        {
        buffer[index - buf_index] = *(str+index); //копируем символ текущей строки в подстроку
        switch(buffer[index - buf_index]) //смотрим, чо это за символ
            {
            case ')':
                if (numL == 0)
                    {
                    buffer[index - buf_index] = '\0'; //если счетчик скобочек верный, ставим символ конца строки
                    ++index;    //устанавливаем индекс на следующий за скобочкой элемент
                    p_str = new char[index-buf_index];
                    if (!p_str)
                        {
                        cout << "Выделение памяти не удалось, программа прервана.";
                        exit(1);
                        }
                    strcpy_s(p_str, index - buf_index, buffer); //и копируем подстроку в новую память
                    return p_str;
                    }
                else
                    numL--;     //уменьшаем счетчик скобок
                break;
            case '(':
                numL++;         //соответственно увеличиваем
                break;
            }
        } while (*(str + index++) != '\0');     //устанавливаем индекс в следующий элемент
    cout << "Вывод за пределы выражения, возможно, плохой ввод." << endl;
    exit(1);
    return p_str;
    }
 
Текущее время: 07:30. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru