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

Подсчитывание начения арифметического выражения (Улучшить программу) - C++

Восстановить пароль Регистрация
 
PG94
2 / 2 / 0
Регистрация: 15.01.2012
Сообщений: 181
03.12.2012, 17:40     Подсчитывание начения арифметического выражения (Улучшить программу) #1
Доброго времени суток.
Нужно написать программу, подсчитывающую значение арифметического выражения( входят натуральные числа, +, *, круглые скобки). Вот код:
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
//Грамматика:
//<Выражение> ::= <слагаемое> {+ <слагаемое>}
//<Слагаемое> ::= <множитель> {* <множитель>}
//<Множитель> ::= <число> | (<выражение>)
#include <iostream>
using namespace std;
typedef char TLexem;
const char _Num = '1',
           _Plus = '+',  
           _Mul = '*',
           _Open = '(',
           _Close = ')',
           _End = '\n';
bool is_error = 0; // флаг ошибки
//получение след. лексемы: _Num, _Plus, _Mul, _Open, _Close или _End
void nextlexem(TLexem& curlex, int& vl);
//вычисление выражения
int expr(TLexem& curlex, int& vl);
//вычисление слагаемого
int item(TLexem& curlex, int& vl);
//вычисление множителя
int mult(TLexem& curlex, int& vl);
//обработка ошибок
void error(TLexem& curlex, int& vl);
int main()
{
    TLexem curlex;
    int vl;
    int v;
    setlocale(LC_ALL, "Russian");
    nextlexem(curlex, vl);
    if(curlex == _End)
        cout << "Введена пустая строка." << endl;
    else
    {   
        v = expr(curlex, vl);
        if(!is_error)
            cout << "Результат = " << v <<endl;
    }
    system("pause");
    return 0;
}
void nextlexem(TLexem& curlex, int& vl)     
{
    char sim;
    sim = cin.get();
    if(isdigit(sim))
    {
        cin.putback(sim);
        cin >> vl;
        curlex = _Num;
    }
    else
        switch(sim)
        {
            case '+':
                curlex = _Plus;
                break;
            case '*':
                curlex = _Mul;
                break;
            case '(':
                curlex = _Open;
                break;
            case ')':
                curlex = _Close;
                break;
            case ' ':                   
                nextlexem(curlex, vl);
                break;
            case '\n':
                curlex = _End;
            default:
                curlex = sim;//записываю сам символ для послед. обработки ошибок
        }
}
int expr(TLexem& curlex, int& vl)
{
    int a;
    a = item(curlex, vl);
    while(curlex == _Plus)
    {
        nextlexem(curlex, vl);
        a+=item(curlex, vl);
    }
    return a;
}
int item(TLexem& curlex, int& vl)
{
    int a;
    a = mult(curlex, vl);
    while(curlex == _Mul)
    {
        nextlexem(curlex, vl);
        a*=mult(curlex, vl);
    }
    return a;
}
int mult(TLexem& curlex, int& vl)
{
    int r = 1;//произвольное значение
    switch(curlex)
    {
        case _Num:
            r = vl;
            nextlexem(curlex, vl);
            break;
        case _Open:
            r = expr(curlex, vl);
            if(curlex == _Close)
            {
                nextlexem(curlex, vl);
                break;
            }
        default:
            error(curlex, vl);
    }
    if(curlex!= _Plus && curlex!= _Mul && curlex!= _End)//следующая лексема после множителя не '*' , не '+' и не '\n'
        error(curlex, vl);
    return r;
}
void error(TLexem& sim, int& vl)
{
    if(sim == _Open || sim == _Close)
        cout << "Ошибка: неверная расстановка скобок." << endl;
    else
        cout << "Ошибка: введён символ '" << sim << "' не являющийся частью выражения, или значение которого в данной позиции не определено." << endl;
    is_error = 1;
    while(sim!= _End)
        nextlexem(sim, vl);
}
Подскажите:
1) Как лучше обработать возможные ошибки при вводе данных с выводом как можно точных сообщение ( с учётом того, что в последующем в программу нужно
добавить вычитание на нат. числах, целочисленное деление и может быть обработку не нат - ых, но и целых чисел).
2) Оптимальный ли в данном случае способ получения следующей лексемы?
Буду очень признателен и за другие советы по улучшению программы. Заранее благодарю за помощь.

Добавлено через 9 часов 50 минут
P.S. Хотелось бы как - нибудь включить все возможные ошибки ( внутри множителя, в знаке между множителями, слагаемыми, неправильною расстановку скобок) в одну функцию, выдающую своё сообщение для каждого типа и прекращающую вычисление выражение.
Буду также благодарен, если укажете, где об этом ( обработке ошибок в программе, решающей данную задачу) можно прочесть.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.12.2012, 17:40     Подсчитывание начения арифметического выражения (Улучшить программу)
Посмотрите здесь:

C++ Написать программу,которая вычисляет значение арифметического выражения записанного в постфиксной форме,с помощью стека
[C++] Разработать программу для вычисления арифметического выражения и вывода полученного результата C++
C++ Чтение арифметического выражения из файла
C++ Паскаль.Разработать программу для вычисления арифметического выражения и вывода полученного результата
Реализовать программу для вычисления линейного арифметического выражения C++
C++ Написать программу, вычисляющую значение арифметического выражения
Расчет арифметического выражения C++
Составить программу проверки баланса скобок арифметического выражения, введенного с клавиатуры C++

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ответ Создать тему
Опции темы

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