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

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

Восстановить пароль Регистрация
 
Assassin1307199
0 / 0 / 0
Регистрация: 26.06.2013
Сообщений: 16
01.05.2014, 13:31     Калькулятор строковый с защитой от дурака #1
Делаю курсовую - нужно сделать строковый калькулятор с защитой от дурака. Код не мой, я добавил только то, что теперь выдает ошибку при вводе буквы. Теперь надо сделать предупредение о том что есть только закрытая, но нет открытой скобки, а также, если 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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#include "stdafx.h"
#include <iostream>
#include <stack>
#include <Windows.h>
#include <stdlib.h>
#include <iostream>
#include <iomanip>
 using namespace std;
 
 double number();
double factor();
double expr();
double brackets();
 
//////////////////////////////////////////MAIN MAIN MAIN
int main()
{ 
    
    setlocale(LC_ALL, "Rus");
    
    double n;
    cout << "Введите выражение(и нажмите Enter): \t";
    n = expr();
    cout << "Результат вычисления: \t" <<setprecision(6) << n <<endl;
    cin.get();
    getchar();
    return 0;
}
 ////////////////////////////////////////////4444444444444444444444444444444444444444444444444444
double number()
{
    double result = 0.0;
    double k = 10.0;
    int sign = 1;
    char c;
 
    c = cin.get();
 
    while (c == ' ')
        c = cin.get();
 
    if (c == '-')
        sign = -1;
    else
        cin.putback(c);
 
    while (true)
    {
        c = cin.get();
 
        while (c == ' ')
            c = cin.get();
        
        if(isalpha(c))
        { cout<<"Калькулятор работает только с численными значениями."<<endl;
         getchar(); getchar(); exit(-1); } 
 
        if (c >= '0' && c <= '9')
            result = result * 10.0 + (c-'0');
        else
        {
           cin.putback(c);
            break;
        }
    }
 
    c = cin.get();
 
    if (c == '.')
    {
        while (true)
        {
            c = cin.get();
 
            if (c >= '0' && c <= '9')
            {
                result += (c - '0') / k;
                k *= 10.0;
            }
            else
            {
                cin.putback(c);
                break;
            }
        }
    }
    else
        cin.putback(c);
 
    return sign * result;
}
 //////////////////////////////////////////22222222222222222222222222222222222222222222222
double factor()
{
    double result = brackets();
    double temp;
    char c;
 
    while (true)
    {
        c = cin.get();
 
        while (c == ' ')
            c = cin.get();
 
        switch (c)
        {
        case '*':
            result *= brackets();
            break;
        case '/':
            temp = brackets();
 
            if (temp == 0.0)
            {
                cout << "Деление на нуль!" << endl; getchar();getchar();
                exit(-1);
            }
 
            result /= temp;
            break;
        default:
           cin.putback(c);
            return result;
        }
    }
}
 ////////////////////////111111111111111111111111111111111111111
double expr()
{
    double result = factor();
    char c;
 
    while (true)
    {
        c = cin.get();
 
        while (c == ' ')
            c = cin.get();
 
        switch (c)
        {
        case '+':
            result = result + factor();
            break;
        case '-':
            result = result - factor();
            break;
        default:
            cin.putback(c);
            return result;
        }
    }
}
//////////////////////////////////3333333333333333333333333333333333333
double brackets()
{
    double result;
    int sign = 1;
    char c;
    int open=0;
   int close=0;
    c = cin.get();
 
    while (c == ' ')
        c = cin.get();
 
    if (c == '-')
    {
        sign = -1;
        c = cin.get();
    }
 
    while (c == ' ')
        c = cin.get();
 
    if (c == '(')
    {
        open++;
        result = sign * expr();
 
        c = cin.get();
 
        if (c != ')')
        {
            cout << "Неверная расстановка скобок!" <<endl; getchar();
            exit(-1);
        }
        else{close++;}
     
        return result;
    }
    else
    {
       cin.putback(c);
 
        return sign * number();
    }
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.05.2014, 13:31     Калькулятор строковый с защитой от дурака
Посмотрите здесь:

C++ Строковый калькулятор
C++ Дан строковый файл. Создать новый строковый файл, содержащий все строки исходного файла наименьшей длины (в том же порядке).
Защита от дурака C++
C++ Защита от дурака
защита от дурака C++
C++ Строковый массив (объявить пустой глобальный строковый массив из 16 элементов)
C++ Защита от дурака
C++ Калькулятор выражений(строковый) через бинарное дерево

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Rifle
 Аватар для Rifle
25 / 25 / 5
Регистрация: 15.11.2012
Сообщений: 93
Завершенные тесты: 4
01.05.2014, 13:59     Калькулятор строковый с защитой от дурака #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
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;
    }
Yandex
Объявления
01.05.2014, 13:59     Калькулятор строковый с защитой от дурака
Ответ Создать тему
Опции темы

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