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

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

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Шаблоны без параметров, что это? http://www.cyberforum.ru/cpp-beginners/thread1087191.html
Наткнулся во включаемом файле iosfwd в Visual Studio 2013 на такое определение:template<> struct char_traits<char>Вроде как похоже на определение шаблона структуры, но почему параметры шаблона пустые (зачем тогда вообще тут нужен шаблон?) и почему после char_traits стоят скобочки с параметром шаблона? Тут же должно стоять новое имя структуры? Ничего не пойму.
C++ Передача std::vector между классами Класс Data служит для инициализации переменных. Класс А - для обработки данных. В классе А меняются данные в контейнере std::vector (размер конейнера может меняться, но скорее нет). Правильно ля я делаю? Естьт ли тут место умным указателям? Сlass Data: Data.h: #ifndef DATA_H_ #define DATA_H_ class Data { public: Data(); http://www.cyberforum.ru/cpp-beginners/thread1087173.html
C++ Использование рекурсивной функции при написании простой игры
Суть такова: У нас имеется доска 5*5 ,есть шахматная фигура коня,которая должна обойти всю доску Что в данном коде не так?? #include <Windows.h> #include <iostream> using namespace std; const int size=5; int a={0};
C++ Как работает istreambuf_iterator?
Всем привет! Уважаемые форумчане, расскажите пожалуйста принцип работы istreambuf_iterator и ostreambuf_iterator. Перелопатил кучу информации в книгах, там вроде написано, но вдуплить не могу... Хотелось бы простым языком и с примерами. Как работать с istream_iterator и ostream_iterator понятно.
C++ Решение линейного уравнения http://www.cyberforum.ru/cpp-beginners/thread1087149.html
Напишите функцию,которая решает линейное уравнение ax+b=0 и записывает результат в переменную передаваемую по ссылке. В случае нахождения одного корня функция возвращает 1,в случае бессконечного множества решений (a=0<b=0) -2 , в случае ввода неправильных данных (а=0)-3 Вот программу по нахождению корня линейного уравнения я написал, а вторую часть задания выполнить не получается, а именно:"В...
C++ Не получается сделать задачу Нужно определить возможность существования треугольника по сторонам. Я ввод чисел написал #include <stdio.h> main () { int a,b,c; printf ("введите длины сторон"); scanf ("%d%d%d",&a,&b,&c); , а вот как дальше запустить цикл проверки (a<(c+b)) подробнее

Показать сообщение отдельно
Fene4ka_
87 / 87 / 16
Регистрация: 24.01.2014
Сообщений: 1,196
02.02.2014, 17:39     Калькулятор выводит неверный результат
скобки реализуешь сам, и как-то много строчек получилось там есть лишние функции, но мне было лень их убирать ...
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
#include "stdafx.h"
#include <iostream>
#include <vector>
 
using namespace std;
 
string enter(void); //вводим выражение 
string mist(string); //поиск неверных символом
string clear(void); //очищаем переменные  
bool check_point(int, string); //проверяем наличие лишних точек 
bool right_symbols(char); //проверяем правильность ввода выражения 
bool right_symbols2(char, char); //проверяем правильность ввода знаков
void record(string); //перепись выражения в структуру
void del_point(void); //удаляем лишние точки 
void point_numbers(void); //обрабатываем числа с точкой
void negative_numbers(void); //обрабатываем отрицательные числа
void grade(void); //возводим все числа в степень  
void second_order(void); //умножаем или делим числа 
void third_order(void); //складываем или вычетаем числа
void rezult(); //выводим результат
void help(void); //выводим справку 
 
struct detail
{
    vector<double> Number;//содержит числа выражения
    vector<char> symbol;//содержит знаки выражения
    vector<int> Ind;//номера знаков выражения в строке
}stTerm;
 
 
int _tmain(int argc, _TCHAR* argv[])
{
    string sTerm; //сюда будет записываться наше выражение
    short int iStart = 0; //варианты выбора
    setlocale(0, "");
    while (iStart != 3)
    {
        system("cls");
        cout<<"Введите 1 для получения справки"<<endl;
        cout<<"Введите 2 для использование калькулятора"<<endl;
        cout<<"Введите 3 для выхода"<<endl;
        cin>>iStart;
        switch (iStart)
        {
        case 1:{ //получаем справку
                help();
                break;
               }
        case 2:{ //производим вычисления
                cout<<"Введите выражение и намжите = для продолжения : ";
                sTerm = enter(); //вводим выражение
                sTerm = mist(sTerm); //переписываем массив в правильном виде
                sTerm = mist(sTerm); //вызываем два раза, так как плюсы с первого раза не всегда удаляет
                record(sTerm);//перепись выражения в структуру
                if (stTerm.Number.size() < 2) //проверяем кол-во веденных переменых, если меньше двух, то прерываем циклы
                {
                    cout<<"Неверное число переменных"<<endl;
                    system("pause");
                    break;
                }
                system("cls");
                del_point(); //удаляем лишние точки
                cout<<">";
                for (int i = 0; i < sTerm.size(); i++)
                    cout<<sTerm[i];
                point_numbers(); //обрабатываем числа с точкой
                negative_numbers(); //обрабатываем отрицательные числа
                grade();//возводим все числа в степень
                second_order(); //умножаем и делим числа
                third_order(); //складываем или вычетаем числа      
                cout<<endl<<'='<<stTerm.Number[0]<<endl;
                cout<<endl;
                system("pause");
                break;
               }
        case 3:{ //выходим из программы
                _exit(1);
                break;
               }
        default:cout<<"Неверный выбор"<<endl;
        }
        sTerm = clear(); //очищаем переменные
    }
}
 
string enter(void)
{
    char x(2); 
    string term;
    while (cin>>x) //вводим выражение
        if (x!='=') //прерываем ввод после ввода =
        {
            stTerm.Number.push_back(0); //создаем незанятые элементы вектора для последущего их заполнения
            term+=x; //записываем все в переменную типа стринг
        }
        else
            break;
    return term;
}
 
string mist(string term)
{
    string expr; //промежуточная переменная
    for (int i = 0; i < term.length()-1; i++)
    {
        //условие пропускает только определенные символы, также проверяет на следование знака за знаком(считается ошибкой) и проверяет точки
        if ((right_symbols(term[i]))&&(right_symbols2(term[i], term[i+1]))
            &&(check_point(i, term)))
             //ограничиваем ввод допустимых символом
            expr+=term[i];
    }
    //последний символ должен являться цифрой
    if ((term[term.length()-1] == '1')||(term[term.length()-1] == '2')||(term[term.length()-1] == '3')||(term[term.length()-1] == '4')||
        (term[term.length()-1] == '5')||(term[term.length()-1] == '6')||(term[term.length()-1] == '7')||
             (term[term.length()-1] == '8')||(term[term.length()-1] == '9')||(term[term.length()-1] == '0')) expr+=term[term.length()-1];
    return expr;
}
 
void record(string term)
{
    int iK = 0;
    for (int i = 0; i<term.length(); i++) //записываем нужные значение в вектора структутры
        switch (term[i])
        {
            case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '0':
            {
                //если нам попадается цифра и элемент вектора еще не был занят, то просто туда записываем цифру
                if (stTerm.Number[iK] == 0)
                    stTerm.Number[iK] = term[i]-48;
                //а если занят, то умножаем эту цифру на 10 (чтобы получить двузначное число) и прибовляем следущую цифру
                else
                    stTerm.Number[iK] = stTerm.Number[iK]*10+(term[i]-48);
                break;
            }
        default:
            {
                //если не цифра - значит записывается знак и помечается его индекс ( нужен для выполнение действий с некоторыми знаками)
                iK++;
                stTerm.symbol.push_back(term[i]);
                stTerm.Ind.push_back(i);
            }
        }
    //если остались лишние элементы в векторе - удалеяем их, чтобы не занимали память :)
    for (int i = stTerm.Number.size()-1; stTerm.Number[i] == 0.0; i--) //удаляем лишние нули из вектора чисел
        stTerm.Number.erase(stTerm.Number.begin()+i);
}
 
void grade(void)
{
    for (int i = 0; i < stTerm.symbol.size(); i++) //возводим в степень числа
        if (stTerm.symbol[i] == '^')
        {
            //возводим число в степень и записываем его в вектор
            stTerm.Number[i] = pow(stTerm.Number[i], stTerm.Number[i+1]);
            //удаляем элементы вектора знаков и цифры степени
            stTerm.Number.erase(stTerm.Number.begin()+i+1);
            stTerm.symbol.erase(stTerm.symbol.begin()+i);
            i--; //для надежности
        }
}
 
void rezult()
{
        cout<<stTerm.Number[0]<<endl;
}
 
void second_order(void)
{
    for (int i = 0; i < stTerm.symbol.size(); i++) //умножаем и делим числа
        switch (stTerm.symbol[i])
        {
        case '*':{
                    //[1]просто умножаем число на число
                    stTerm.Number[i] *=stTerm.Number[i+1];
                    //удаляем лишние элементы вектора
                    stTerm.Number.erase(stTerm.Number.begin()+i+1);
                    stTerm.symbol.erase(stTerm.symbol.begin()+i);
                    //для надежности
                    i--;
                    break;
                 }
        case '/':{
                    //читать [1]
                    stTerm.Number[i] /=stTerm.Number[i+1];
                    stTerm.Number.erase(stTerm.Number.begin()+i+1);
                    stTerm.symbol.erase(stTerm.symbol.begin()+i);
                    i--;
                    break;
                 }
        }
}
 
void third_order(void)
{
    for (int i = 0; i < stTerm.symbol.size(); i++) //умножаем и делим числа
        switch (stTerm.symbol[i])
        {
        case '+':{
                    //читать [1] в second_order()
                    stTerm.Number[i] +=stTerm.Number[i+1];
                    stTerm.Number.erase(stTerm.Number.begin()+i+1);
                    stTerm.symbol.erase(stTerm.symbol.begin()+i);
                    i--;
                    break;
                 }
        case '-':{
                    //читать [1] в second_order()
                    stTerm.Number[i] -=stTerm.Number[i+1];
                    stTerm.Number.erase(stTerm.Number.begin()+i+1);
                    stTerm.symbol.erase(stTerm.symbol.begin()+i);
                    i--;
                    break;
                 }
        }
}
 
void negative_numbers(void)
{
    for (int i = 0; i < stTerm.symbol.size(); i++) //обрабатываем отрицательные числа
    {
        //делаем отрицательным первое число [2]
        if ((stTerm.symbol[i] == '-')&&(i == 0)&&(stTerm.Ind[0] == 0))
        {
            stTerm.Number.erase(stTerm.Number.begin()+i); //завалялся лишний ноль
            stTerm.Number[i] =stTerm.Number[i]*(-1); //просто делаем число отрицательным
            //удаляем лишние элеметы вектора
            stTerm.symbol.erase(stTerm.symbol.begin()+i);
            stTerm.Ind.erase(stTerm.Ind.begin()+i);
        }
        //делаем отрицательным остальные числа, читать [2] в negative_numbers()
        if ((stTerm.symbol[i] == '-')&&(i > 0))
            if (stTerm.Ind[i-1]+1 == stTerm.Ind[i])
            {
                stTerm.Number.erase(stTerm.Number.begin()+i);
                stTerm.Number[i] =stTerm.Number[i]*(-1);
                stTerm.symbol.erase(stTerm.symbol.begin()+i);
                stTerm.Ind.erase(stTerm.Ind.begin()+i);
            }
    }
}
 
string clear(void)
{
    stTerm.Number.erase(stTerm.Number.begin(), stTerm.Number.end()); //очищаем вектор чисел
    stTerm.symbol.erase(stTerm.symbol.begin(), stTerm.symbol.end()); //очищаем вектор знаков
    stTerm.Ind.erase(stTerm.Ind.begin(), stTerm.Ind.end()); //очищаем вектор индексов
    return "";
}
 
void help(void)
{
    system("cls");
    cout<<"Используемая версия программы : 0.2а."<<endl;
    cout<<"Калькулятор умеет обрабатывать длинные выражения с возведением в степень, делением, умножением, сложением, вычитанием."<<endl;
    cout<<"Калькулятор умеет обрабатывать отрицательные числа."<<endl;
    cout<<"Калькулятор умеет обрабатывать дробные числа"<<endl;
    cout<<"Калькулятор пока-что не умеет обрабатывать скобки."<<endl;
    cout<<"В выражении типа <<05+2=>> <<0>> считываться не будет."<<endl;
    cout<<"Для правильной работы калькулятора при делении используйте значок '/', а не '\\'."<<endl<<endl<<endl;
    system("pause");
}
 
void del_point(void)
{
    //удаляем затерявшиеся точки, для надежности
    for (int i = 0; i < stTerm.symbol.size()-1; i++)
        if (((stTerm.symbol[i] == '.')||(stTerm.symbol[i] == '.'))&&((stTerm.symbol[i+1] == '.')||(stTerm.symbol[i+1] == ',')))
        {
            stTerm.Number.erase(stTerm.Number.begin()+i+2);
            stTerm.symbol.erase(stTerm.symbol.begin()+i+1);
            stTerm.Ind.erase(stTerm.Ind.begin()+i+1);
            i--;
        }
}
 
void point_numbers(void)
{
    double dNum = 0; //числитель
    double dDenum = 1; //знаменатель
    int iNumb = 0; //число символов после запятой
    int iK; //содержит промежуточное значение
    for (int i = 0; i < stTerm.symbol.size(); i++)
        if ((stTerm.symbol[i] == '.')||(stTerm.symbol[i] == ','))
        {
            iK = stTerm.Number[i+1]; //записываем число после запятой
            while (iK!=0) //находим кол-во цифр после запятой, для знаменателя
            {
                iK /= 10;
                iNumb++; //тут кол-во цифр
            }
            dNum = pow(10.0, iNumb)*stTerm.Number[i]+stTerm.Number[i+1]; //высчитываем числитель дроби
            dDenum = pow(10.0 , iNumb); //знаменатель дроби
            stTerm.Number[i] = dNum / dDenum; //получаем значение
            //удаляем лишнии элементы
            stTerm.Number.erase(stTerm.Number.begin()+i+1);
            stTerm.symbol.erase(stTerm.symbol.begin()+i);
            stTerm.Ind.erase(stTerm.Ind.begin()+i);
            i--; //для надежности
            iNumb = 0; //обнуляем переменную для последущих вычислений
        }
}
 
bool check_point(int k, string term)
{
    //если символ точка или запятая ( после второго по счету символа ) то ...
    if (((term[k] == '.')||(term[k] == ','))&&(k>1))
        for (int i = k-1; i > 0; i--)
        {
            //движемся назад и если натыкаемся на символ-знак действия, то все нормально - записываем символ в стринг
            if ((term[i] == '+')||(term[i] == '-')||(term[i] == '/')||(term[i] == '*')||(term[i] == '^')) 
            {
                return true;
                break;
            }
            //а если встречаем точку или запятую, то незаписываем в стринг
            else if ((term[i] == '.')||(term[i] == ',')) 
            {
                return false;
                break;
            }
        }
    else return true;
    //тоже самое, что и выше, но сравнивает исключительно с предыдущим символом
    if (((term[k] == '.')||(term[k] == ','))&&(k > 0)&&((term[k-1] == '+')||(term[k-1] == '-')||(term[k-1] == '/')||(term[k-1] == '*')||
        (term[k-1] == '^'))) return false;
    //если самый первый символ точка или запятая, то незаписываем его ( первым символом должна быть цифра )
    if (((term[0] == '.')||(term[k] == ','))&&(k == 0)) return false;
}
 
bool right_symbols(char symbol)
{
    //список символом, которые пройдут проверку :)
    if ((symbol == '1')||(symbol == '2')||(symbol == '3')||(symbol == '4')||(symbol == '5')||(symbol == '6')||(symbol == '7')||
        (symbol == '8')||(symbol == '9')||(symbol == '0')||(symbol == '+')||(symbol == '-')||(symbol == '*')||(symbol == '/')||
        (symbol == '%')||(symbol == '^')||(symbol == '.')||(symbol == ','))
            return true;
    else    return false;
}
 
bool right_symbols2(char symbol, char symbol2)
{
    //список знаков, которые пройдут проверку ( некоторые знаки не должны следовать друг за другом )
    if (((symbol == '+')||(symbol == '-')||(symbol == '*')||(symbol == '/')||(symbol == '%'))&&
        ((symbol2 == '+')||(symbol2 == '-')||(symbol2 == '*')||(symbol2 == '/')||(symbol2 == '%')))
        return false;
    else if ((symbol == '^')&&(symbol2 == '^'))
        return false;
    else
        return true;
}
Добавлено через 1 минуту
даже с комментариями писал пол года назад
 
Текущее время: 04:04. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru