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

Калькулятор логических/арифметических операций(подробности внутри) - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 33, средняя оценка - 4.91
doojkee
 Аватар для doojkee
0 / 0 / 0
Регистрация: 26.03.2012
Сообщений: 8
08.04.2012, 17:29     Калькулятор логических/арифметических операций(подробности внутри) #1
1ый курс одного электротехнического вуза!

Суть программы, которую нужно написать:

Написать нужно на чистом Си

Написать программу калькулятор, вычисляющая значения арифметичекого или логического выражения.
- допуская неограниченное количество вложенных скобок.
- должны полностью соблюдаться приоритеты логич. Арифм. Операций.
- необходимо, чтобы программа умела вычислять значение как введеного с клавиатура и как загруженного с файла.
- вывод как на экран так и в файл.
- дружественное меню для пользователя и интерфейс. (GUI не нужен, все в консоле.)
- возможность задавать параметры командной строки. (понятия не имею, что это.)
- Рекомендуется преобразовывать формулу в обратную польскую запись, но вводить формулу в норм вид.
-сделать автоматическое распознование формулы(логич. & арифметическая) .

Очень прошу помощи в реализации этой программы, буду благодарен за любую помощь, советы, примеры кода, ссылки на статьи, книги и т.д.
Заранее спасибо!
Покупать готовую программу не собираюсь!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.04.2012, 17:29     Калькулятор логических/арифметических операций(подробности внутри)
Посмотрите здесь:

Перегрузка арифметических операций C++
Перегрузка арифметических операций для работы с объектами классов. C++
Вставить между цифрами 1, 2,..., 8, 9 в данном порядке, знак одной из 4-х арифметических операций так, чтобы результат восьми послед-х операций =100 C++
Написать калькулятор логических выражений на С C++
Реализация арифметических операций над вещественными числами C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
stanis-morozov
15 / 15 / 1
Регистрация: 18.03.2012
Сообщений: 91
08.04.2012, 18:46     Калькулятор логических/арифметических операций(подробности внутри) #2
1) Какие операторы ваша программа должна поддерживать (+, -, *, /...) , (|, &...).
2) Дружественно меню - понятие странное, приведите пример работы программы.
3) Как программа должна понимать - читать с экрана или из файла?
4) Чтобы задавать параметры командной строки, нужно сначала определить какие параметры программа должна понимать. Может быть, кстати если в качестве параметры командной строки задан файл, то читать из него, а если нет, то с экрана.
5) Нужно ли сообщать - арифметическое выражение или логическое. К тому же, может я неправильно понимаю, но арифметическое выражение - это то, в котором только арифметические операции, а логическое - в котором только логические? А что, не могут быть в выражении и те, и другие? Например:
(5 + 7) * 8 & 3
6) Знакомы ли вы с STL?
Jupiter
08.04.2012, 19:01
  #3

Не по теме:

Цитата Сообщение от stanis-morozov Посмотреть сообщение
Знакомы ли вы с STL?
какой STL в чистом Си!?

stanis-morozov
15 / 15 / 1
Регистрация: 18.03.2012
Сообщений: 91
08.04.2012, 19:10     Калькулятор логических/арифметических операций(подробности внутри) #4
Ой, не заметил, что чистый C. Ну значит 6-ой вопрос отпадает...
doojkee
 Аватар для doojkee
0 / 0 / 0
Регистрация: 26.03.2012
Сообщений: 8
08.04.2012, 20:02  [ТС]     Калькулятор логических/арифметических операций(подробности внутри) #5
Цитата Сообщение от stanis-morozov Посмотреть сообщение
1) Какие операторы ваша программа должна поддерживать (+, -, *, /...) , (|, &...).
2) Дружественно меню - понятие странное, приведите пример работы программы.
3) Как программа должна понимать - читать с экрана или из файла?
4) Чтобы задавать параметры командной строки, нужно сначала определить какие параметры программа должна понимать. Может быть, кстати если в качестве параметры командной строки задан файл, то читать из него, а если нет, то с экрана.
5) Нужно ли сообщать - арифметическое выражение или логическое. К тому же, может я неправильно понимаю, но арифметическое выражение - это то, в котором только арифметические операции, а логическое - в котором только логические? А что, не могут быть в выражении и те, и другие? Например:
(5 + 7) * 8 & 3
6) Знакомы ли вы с STL?
1) Именно так, только еще sqrt(), и степенные выражения.
2) Меню я еще сам пока не думал над этим, но это уже рюшки - не первая необходимость!
3) Это нужно реализовать в меню например:
- 1. Загрузка формулы из файла и ввод адреса файла.
- 2. Ввод формулы вручную.
4) Может быть и так.
5) Нет не могут выражения логич. и арифметич. вводить и считать отдельно.
6) Я могу ошибаться, но все-таки STL ли не для С++??

Есть пример реализации ОПН(З) на С++, но мне от этого как-то не легче:

C++ (Qt)
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
#include <iostream>
#include <stack>
using namespace std;
bool delim (char c) 
{
    return c == ' ';
}
bool is_op (char c) 
{
    return c=='+' || c=='-' || c=='*' || c=='/' || c=='%';
}
int priority (char op) 
{
    return
        op == '+' || op == '-' ? 1 :
        op == '*' || op == '/' || op == '%' ? 2 :
        -1;
}
void process_op (stack<int>& st, char op) 
{
    int r = st.top();  
    st.pop();
    int l = st.top();  
    st.pop();
    switch (op)
    {
        case '+':  st.push(l + r);  break;
        case '-':  st.push(l - r);  break;
        case '*':  st.push(l * r);  break;
        case '/':  st.push(l / r);  break;
        case '%':  st.push(l % r);  break;
    }
}
int calc (char *s)
{
    stack <int> Int;
    stack <char> Char;
    for (int i=0; i<strlen(s);i++)
    {
        if (!delim (s[i]))
            if (s[i] == '(')
                Char.push('(');
            else if (s[i] == ')') 
            {
                while (Char.top() != '(')
                    process_op (Int, Char.top()), Char.pop();
                Char.pop();
            }
            else if (is_op (s[i])) 
            {
                char curop = s[i];
                while (!Char.empty() && priority(Char.top()) >= priority(s[i]))
                    process_op (Int, Char.top()), Char.pop();
                Char.push(curop);
            }
            else 
            {
                string operand;
                while (s[i]>='a'&&s[i]<='z'||isdigit(s[i]))
                    operand += s[i++];
                --i;
                if (isdigit (operand[0]))
                    Int.push(atoi(operand.c_str()));
                else
                {
                    char* str_ptr=new char[operand.length()+1]();
                    strcpy(str_ptr,operand.c_str());
                    Int.push(atoi(str_ptr));
                }
            }
    }
    while (!Char.empty())
        process_op (Int, Char.top()),Char.pop();
    return Int.top();
}
 
void main()
{
    setlocale(LC_ALL,"RUS");
    char s[100];
    cout<<"Введите выражение:";
    cin>>s;
    int rez=calc(s);
    cout<<"Результат:"<<rez;
    cout<<"\n";
}
stanis-morozov
15 / 15 / 1
Регистрация: 18.03.2012
Сообщений: 91
08.04.2012, 22:44     Калькулятор логических/арифметических операций(подробности внутри) #6
Да и, наверное последний вопрос и я вам постараюсь написать код: числа могут дробными и отрицательными, так? Если да, то разделитель целой и дробной частей - точка или запятая? Или и то и другое считать?
dr.curse
 Аватар для dr.curse
386 / 342 / 16
Регистрация: 11.10.2010
Сообщений: 1,907
08.04.2012, 22:49     Калькулятор логических/арифметических операций(подробности внутри) #7
Цитата Сообщение от doojkee Посмотреть сообщение
- Рекомендуется преобразовывать формулу в обратную польскую запись, но вводить формулу в норм вид.
мне больше рекурсивный спуск нравится, но с помощю него тоже можно преобразовать в ОПН
doojkee
 Аватар для doojkee
0 / 0 / 0
Регистрация: 26.03.2012
Сообщений: 8
08.04.2012, 23:01  [ТС]     Калькулятор логических/арифметических операций(подробности внутри) #8
Цитата Сообщение от stanis-morozov Посмотреть сообщение
Да и, наверное последний вопрос и я вам постараюсь написать код: числа могут дробными и отрицательными, так? Если да, то разделитель целой и дробной частей - точка или запятая? Или и то и другое считать?
а как вам удобнее, я и так вам буду безумно благодарен.

Добавлено через 1 минуту
Цитата Сообщение от aram_gyumri Посмотреть сообщение
мне больше рекурсивный спуск нравится, но с помощю него тоже можно преобразовать в ОПН
я почитаю об этом. Или может вы приведите пример или статью? Или просто гугл в помощь?
stanis-morozov
15 / 15 / 1
Регистрация: 18.03.2012
Сообщений: 91
09.04.2012, 18:56     Калькулятор логических/арифметических операций(подробности внутри) #9
Ну вот вроде я и написал код. Писал рекурсивным спуском, чуть попозже, если хотите напишу, как это все работает. Программа поддерживает для арифметических операций и отрицательные, и дробные числа, а для логических операций - только натуральные. Насколько я знаю для дробных чисел логические операции не определены, а вот с отрицательными вполне можно сделать. Просто там уже нужно будет анализировать - минус - это знак числа или арифметическая операция. Еще могу заметить, что программа не проверяет расстановку скобок. Если по ходу вычислений становится очевидно, что скобки стоят неправильно, то программа конечно сообщит об этом. Но во многих случаях она этого не делает. В общем-то это все можно дописать, и если хотите, я это сделаю, просто пока я старался написать только самое необходимое. Также, я реализовал файловый ввод-вывод. Если в командной строке задан первый параметр, то программа будет читать пример из него. Если же задан еще и второй параметр, то программа будет читать из первого, а записывать ответ во второй файл.
Я постарался отобразить в коде основные ваши вопросы, а там довести до красивого оформления уже можно без проблем. Если хотите, я доделаю, только напишите, что конкретно нужно реализовать и как это должно выглядеть.

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
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
#include <stdio.h>
#include <string.h>
#include <math.h>
 
#define _Num 0
#define _Plus 1
#define _Mul 2
#define _Open 3
#define _Close 4
#define _Min 5
#define _Div 6
#define _End 7
#define _Pow 8
#define _And 9
#define _Or 10
 
int currlex;
double vl_a;
int vl_l;
int pos = 0;
int err = 0;
char primer[10000];
int arifm = 0, logic = 0;
 
double power();
double item_a();
double expr_a();
double mult();
void nextlex_a();
void error();
 
int item_l();
int And();
int expr_l();
void nextlex_l();
 
double power(){
    double a;
    if (currlex == _Num){
        a = vl_a;
        nextlex_a();
        return a;
    }
    else if (currlex == _Open){
        nextlex_a();
        a = expr_a();
        if (currlex == _Close) nextlex_a();
        else error();
        return a;
    }
    else error();
}
 
double mult(){
    double a, b;
    a = power();
    while (currlex == _Pow){
        nextlex_a();
        b = power();
        //printf("%lf %lf\n", a, b);
        a = pow(a, b);
    }
    return a;
}
 
 
void error(){
    err = 1;
}
 
 
double item_a(){
    double a, b;
    int c;
    a = mult();
    while ((currlex == _Mul) || (currlex == _Div)){
        c = currlex;
        nextlex_a();
        b = mult();
        if (c == _Mul) a *= b;
        else {
            if (b != 0)
                a /= b;
            else error();
        }
    }
    return a;
}
 
double expr_a(){
    double a, b;
    int c;
    a = item_a();
    while ((currlex == _Plus) || (currlex == _Min)){
        c = currlex;
        nextlex_a();
        b = item_a();
        if (c == _Plus) a += b;
        else a -= b;
    }
    return a;
}
 
 
void nextlex_a(){
    long long comma = 1;
    int k = 1;
    if (primer[pos] == '+') currlex = _Plus;
    else if (primer[pos] == '*') currlex = _Mul;
    else if (primer[pos] == '(') currlex = _Open;
    else if (primer[pos] == ')') currlex = _Close;
    else if (primer[pos] == 0) currlex = _End;
    else if (primer[pos] == '/') currlex = _Div;
    else if (primer[pos] == '^') currlex = _Pow;
    else if (((primer[pos] >= '0') && (primer[pos] <= '9')) || (primer[pos] == '-')) {
        if (((primer[pos] >= '0') && (primer[pos] <= '9')) || ((pos == 0) && (primer[pos] == '-')) || ((currlex == _Open) && (primer[pos] == '-'))){
            if (primer[pos] == '-') {
                k = -1;
                pos++;
            }
            currlex = _Num;
            vl_a = 0;
            while ((primer[pos] >= '0') && (primer[pos] <= '9')){
                vl_a *= 10;
                vl_a += primer[pos] - 48;
                pos++;
            }
            if ((primer[pos] == '.') || (primer[pos] == ',')){
                pos++;
                while ((primer[pos] >= '0') && (primer[pos] <= '9')){
                    comma *= 10;
                    vl_a += (primer[pos] - 48) / (double)comma;
                    pos++;
                }
            }
            vl_a *= k;
            pos--;
        }
        else currlex = _Min;
    }
    pos++;
}
 
 
void nextlex_l()
{
    if (primer[pos] == '|')
    {
        currlex = _Or;
        pos++;
    }
    else if (primer[pos] == '&')
    {
        currlex = _And;
        pos++;
    }
    else if (primer[pos] == '(')
    {
        currlex = _Open;
        pos++;
    }
    else if (primer[pos] == ')')
    {
        currlex = _Close;
        pos++;
    }
    else if (primer[pos] >= '0' && primer[pos] <= '9')
    {
        currlex = _Num;
        vl_l = 0;
        while (primer[pos] >= '0' && primer[pos] <= '9')
        {
            vl_l *= 10;
            vl_l += primer[pos] - 48;
            pos++;
        }
    }
}
 
 
int And(){
    int a;
    if (currlex == _Num){
        a = vl_l;
        nextlex_l();
        return a;
    }
    else if (currlex == _Open){
        nextlex_l();
        a = expr_l();
        if (currlex == _Close) nextlex_l();
        else error();
        return a;
    }
    else error();
}
 
 
 
int item_l()
{
    int a, b;
    int c;
    a = And();
    while (currlex == _And){
        c = currlex;
        nextlex_l();
        b = And();
        a &= b;
    }
    return a;
}
 
 
int expr_l()
{
    int a, b;
    int c;
    a = item_l();
    while (currlex == _Or)
    {
        c = currlex;
        nextlex_l();
        b = item_l();
        a |= b;
    }
    return a;
}
 
 
 
 
double count(char *s)
{
    double res_a;
    int res_l;
    pos = 0;
    err = 0;
    strcpy(primer, s);
    if (arifm)
    {
        nextlex_a();
        res_a = expr_a();
        return res_a;
    }
    else
    {
        nextlex_l();
        res_l = expr_l();
        return res_l;
    }
 
}
 
 
 
 
int main(int argc, char** argv)
{
    FILE *fin, *fout;
    int file_out = 0;
    char s[10000];
    if (argc > 1)
    {
        fin = fopen(argv[1], "r");
        if (argc > 2)
        {
            fout = fopen(argv[2], "w");
            file_out = 1;
        }
        char ch;
        int i = 0;
        do
        {
            fscanf(fin, "%c", &ch);
            if (ch >= '0' && ch <= '9')
            {
                s[i] = ch;
                i++;
            }
            else if (ch == '.' || ch == ',' || ch == '(' || ch == ')')
            {
                s[i] = ch;
                i++;
            }
            else if (ch == ' ' || ch == '\t' || ch == '\n')
            {
 
            }
            else if (ch == '+' || ch == '-' || ch == '*' || ch == '/')
            {
                s[i] = ch;
                i++;
                arifm = 1;
            }
            else if (ch == '&' || ch == '|')
            {
                s[i] = ch;
                i++;
                logic = 1;
            }
            else
            {
                printf("expr_aession is incorrect. Unknown simbol \'%c\'\n", ch);
            }
        } while (ch != '\n');
        s[i] = 0;
 
    }
    else
    {
        char ch;
        int i = 0;
        do
        {
            scanf("%c", &ch);
            if (ch >= '0' && ch <= '9')
            {
                s[i] = ch;
                i++;
            }
            else if (ch == '.' || ch == ',' || ch == '(' || ch == ')')
            {
                s[i] = ch;
                i++;
 
                if (ch == '.' || ch == ',')
                {
                    arifm = 1;
                }
            }
            else if (ch == ' ' || ch == '\t' || ch == '\n')
            {
 
            }
            else if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^')
            {
                s[i] = ch;
                i++;
                arifm = 1;
            }
            else if (ch == '&' || ch == '|')
            {
                s[i] = ch;
                i++;
                logic = 1;
            }
            else
            {
                printf("expr_aession is incorrect. Unknown simbol \'%c\'\n", ch);
            }
        } while (ch != '\n');
        s[i] = 0;
    }
 
    if (arifm && logic)
    {
        printf("Error: It's arifmetic and logical expr_aession!\n");
        return 0;
    }
    if (arifm)
    {
        double res = count(s);
        if (err)
        {
            if (file_out)
            {
                fprintf(fout, "Incorrect expression!\n");
            }
            else
            {
                printf("Incorrect expression!\n");
            }
        }
        else
        {
            if (file_out)
            {
                fprintf(fout, "%lf\n", res);
            }
            else
            {
                printf("%ld\n", res);
            }
        }
    }
    else
    {
        int res = count(s);
        if (err)
        {
            if (file_out)
            {
                fprintf(fout, "Incorrect expression!\n");
            }
            else
            {
                printf("Incorrect expression!\n");
            }
        }
        else
        {
            if (file_out)
            {
                fprintf(fout, "%d\n", res);
            }
            else
            {
                printf("%d\n", res);
            }
        }
    }
 
 
    return 0;
}
Дебажил не очень много, если программа будет работать неправильно - пишите!
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.04.2012, 21:46     Калькулятор логических/арифметических операций(подробности внутри)
Еще ссылки по теме:

C++ Класс длинная арифметика с поддержкой арифметических операций
Выполнение битовых логических операций C++
C++ Корректное написание логических операций

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

Или воспользуйтесь поиском по форуму:
doojkee
 Аватар для doojkee
0 / 0 / 0
Регистрация: 26.03.2012
Сообщений: 8
09.04.2012, 21:46  [ТС]     Калькулятор логических/арифметических операций(подробности внутри) #10
Цитата Сообщение от stanis-morozov Посмотреть сообщение
Ну вот вроде я и написал код. Писал рекурсивным спуском, чуть попозже, если хотите напишу, как это все работает. Программа поддерживает для арифметических операций и отрицательные, и дробные числа, а для логических операций - только натуральные. Насколько я знаю для дробных чисел логические операции не определены, а вот с отрицательными вполне можно сделать. Просто там уже нужно будет анализировать - минус - это знак числа или арифметическая операция. Еще могу заметить, что программа не проверяет расстановку скобок. Если по ходу вычислений становится очевидно, что скобки стоят неправильно, то программа конечно сообщит об этом. Но во многих случаях она этого не делает. В общем-то это все можно дописать, и если хотите, я это сделаю, просто пока я старался написать только самое необходимое. Также, я реализовал файловый ввод-вывод. Если в командной строке задан первый параметр, то программа будет читать пример из него. Если же задан еще и второй параметр, то программа будет читать из первого, а записывать ответ во второй файл.
Я постарался отобразить в коде основные ваши вопросы, а там довести до красивого оформления уже можно без проблем. Если хотите, я доделаю, только напишите, что конкретно нужно реализовать и как это должно выглядеть.

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
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
#include <stdio.h>
#include <string.h>
#include <math.h>
 
#define _Num 0
#define _Plus 1
#define _Mul 2
#define _Open 3
#define _Close 4
#define _Min 5
#define _Div 6
#define _End 7
#define _Pow 8
#define _And 9
#define _Or 10
 
int currlex;
double vl_a;
int vl_l;
int pos = 0;
int err = 0;
char primer[10000];
int arifm = 0, logic = 0;
 
double power();
double item_a();
double expr_a();
double mult();
void nextlex_a();
void error();
 
int item_l();
int And();
int expr_l();
void nextlex_l();
 
double power(){
    double a;
    if (currlex == _Num){
        a = vl_a;
        nextlex_a();
        return a;
    }
    else if (currlex == _Open){
        nextlex_a();
        a = expr_a();
        if (currlex == _Close) nextlex_a();
        else error();
        return a;
    }
    else error();
}
 
double mult(){
    double a, b;
    a = power();
    while (currlex == _Pow){
        nextlex_a();
        b = power();
        //printf("%lf %lf\n", a, b);
        a = pow(a, b);
    }
    return a;
}
 
 
void error(){
    err = 1;
}
 
 
double item_a(){
    double a, b;
    int c;
    a = mult();
    while ((currlex == _Mul) || (currlex == _Div)){
        c = currlex;
        nextlex_a();
        b = mult();
        if (c == _Mul) a *= b;
        else {
            if (b != 0)
                a /= b;
            else error();
        }
    }
    return a;
}
 
double expr_a(){
    double a, b;
    int c;
    a = item_a();
    while ((currlex == _Plus) || (currlex == _Min)){
        c = currlex;
        nextlex_a();
        b = item_a();
        if (c == _Plus) a += b;
        else a -= b;
    }
    return a;
}
 
 
void nextlex_a(){
    long long comma = 1;
    int k = 1;
    if (primer[pos] == '+') currlex = _Plus;
    else if (primer[pos] == '*') currlex = _Mul;
    else if (primer[pos] == '(') currlex = _Open;
    else if (primer[pos] == ')') currlex = _Close;
    else if (primer[pos] == 0) currlex = _End;
    else if (primer[pos] == '/') currlex = _Div;
    else if (primer[pos] == '^') currlex = _Pow;
    else if (((primer[pos] >= '0') && (primer[pos] <= '9')) || (primer[pos] == '-')) {
        if (((primer[pos] >= '0') && (primer[pos] <= '9')) || ((pos == 0) && (primer[pos] == '-')) || ((currlex == _Open) && (primer[pos] == '-'))){
            if (primer[pos] == '-') {
                k = -1;
                pos++;
            }
            currlex = _Num;
            vl_a = 0;
            while ((primer[pos] >= '0') && (primer[pos] <= '9')){
                vl_a *= 10;
                vl_a += primer[pos] - 48;
                pos++;
            }
            if ((primer[pos] == '.') || (primer[pos] == ',')){
                pos++;
                while ((primer[pos] >= '0') && (primer[pos] <= '9')){
                    comma *= 10;
                    vl_a += (primer[pos] - 48) / (double)comma;
                    pos++;
                }
            }
            vl_a *= k;
            pos--;
        }
        else currlex = _Min;
    }
    pos++;
}
 
 
void nextlex_l()
{
    if (primer[pos] == '|')
    {
        currlex = _Or;
        pos++;
    }
    else if (primer[pos] == '&')
    {
        currlex = _And;
        pos++;
    }
    else if (primer[pos] == '(')
    {
        currlex = _Open;
        pos++;
    }
    else if (primer[pos] == ')')
    {
        currlex = _Close;
        pos++;
    }
    else if (primer[pos] >= '0' && primer[pos] <= '9')
    {
        currlex = _Num;
        vl_l = 0;
        while (primer[pos] >= '0' && primer[pos] <= '9')
        {
            vl_l *= 10;
            vl_l += primer[pos] - 48;
            pos++;
        }
    }
}
 
 
int And(){
    int a;
    if (currlex == _Num){
        a = vl_l;
        nextlex_l();
        return a;
    }
    else if (currlex == _Open){
        nextlex_l();
        a = expr_l();
        if (currlex == _Close) nextlex_l();
        else error();
        return a;
    }
    else error();
}
 
 
 
int item_l()
{
    int a, b;
    int c;
    a = And();
    while (currlex == _And){
        c = currlex;
        nextlex_l();
        b = And();
        a &= b;
    }
    return a;
}
 
 
int expr_l()
{
    int a, b;
    int c;
    a = item_l();
    while (currlex == _Or)
    {
        c = currlex;
        nextlex_l();
        b = item_l();
        a |= b;
    }
    return a;
}
 
 
 
 
double count(char *s)
{
    double res_a;
    int res_l;
    pos = 0;
    err = 0;
    strcpy(primer, s);
    if (arifm)
    {
        nextlex_a();
        res_a = expr_a();
        return res_a;
    }
    else
    {
        nextlex_l();
        res_l = expr_l();
        return res_l;
    }
 
}
 
 
 
 
int main(int argc, char** argv)
{
    FILE *fin, *fout;
    int file_out = 0;
    char s[10000];
    if (argc > 1)
    {
        fin = fopen(argv[1], "r");
        if (argc > 2)
        {
            fout = fopen(argv[2], "w");
            file_out = 1;
        }
        char ch;
        int i = 0;
        do
        {
            fscanf(fin, "%c", &ch);
            if (ch >= '0' && ch <= '9')
            {
                s[i] = ch;
                i++;
            }
            else if (ch == '.' || ch == ',' || ch == '(' || ch == ')')
            {
                s[i] = ch;
                i++;
            }
            else if (ch == ' ' || ch == '\t' || ch == '\n')
            {
 
            }
            else if (ch == '+' || ch == '-' || ch == '*' || ch == '/')
            {
                s[i] = ch;
                i++;
                arifm = 1;
            }
            else if (ch == '&' || ch == '|')
            {
                s[i] = ch;
                i++;
                logic = 1;
            }
            else
            {
                printf("expr_aession is incorrect. Unknown simbol \'%c\'\n", ch);
            }
        } while (ch != '\n');
        s[i] = 0;
 
    }
    else
    {
        char ch;
        int i = 0;
        do
        {
            scanf("%c", &ch);
            if (ch >= '0' && ch <= '9')
            {
                s[i] = ch;
                i++;
            }
            else if (ch == '.' || ch == ',' || ch == '(' || ch == ')')
            {
                s[i] = ch;
                i++;
 
                if (ch == '.' || ch == ',')
                {
                    arifm = 1;
                }
            }
            else if (ch == ' ' || ch == '\t' || ch == '\n')
            {
 
            }
            else if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^')
            {
                s[i] = ch;
                i++;
                arifm = 1;
            }
            else if (ch == '&' || ch == '|')
            {
                s[i] = ch;
                i++;
                logic = 1;
            }
            else
            {
                printf("expr_aession is incorrect. Unknown simbol \'%c\'\n", ch);
            }
        } while (ch != '\n');
        s[i] = 0;
    }
 
    if (arifm && logic)
    {
        printf("Error: It's arifmetic and logical expr_aession!\n");
        return 0;
    }
    if (arifm)
    {
        double res = count(s);
        if (err)
        {
            if (file_out)
            {
                fprintf(fout, "Incorrect expression!\n");
            }
            else
            {
                printf("Incorrect expression!\n");
            }
        }
        else
        {
            if (file_out)
            {
                fprintf(fout, "%lf\n", res);
            }
            else
            {
                printf("%ld\n", res);
            }
        }
    }
    else
    {
        int res = count(s);
        if (err)
        {
            if (file_out)
            {
                fprintf(fout, "Incorrect expression!\n");
            }
            else
            {
                printf("Incorrect expression!\n");
            }
        }
        else
        {
            if (file_out)
            {
                fprintf(fout, "%d\n", res);
            }
            else
            {
                printf("%d\n", res);
            }
        }
    }
 
 
    return 0;
}
Дебажил не очень много, если программа будет работать неправильно - пишите!
Спасибо большое, отписал вам в лс!
Yandex
Объявления
09.04.2012, 21:46     Калькулятор логических/арифметических операций(подробности внутри)
Ответ Создать тему
Опции темы

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