Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/18: Рейтинг темы: голосов - 18, средняя оценка - 4.89
0 / 0 / 0
Регистрация: 17.11.2019
Сообщений: 6

Калькулятор дробей

30.12.2019, 12:40. Показов 3419. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте! Изучаю С++ по книге Лафоре, там нужно было создать калькулятор дробей в одном из упражнений. Калькулятор работает как надо, но проблемы с циклами, если я ввожу неправильно первую дробь из двух, то запускается бесконечный цикл с надписью "неверный формат дроби 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
// fraction 11.cpp программа для действий с дробями
 
#include <iostream>
#include <cmath>
using namespace std;
 
class fraction
{
private:
    int nominator;
    int denominator;
    static int vsego;
    int nomer;
public:
    fraction(): nominator(1), denominator(1)
    {vsego++; nomer = vsego;}
    fraction(int x, int y) : nominator(x), denominator(y)
    {vsego++; nomer = vsego;}
    void cinfraction()
    {
        char d1;
        do
        {
            cin >> nominator >> d1 >> denominator;
            if (d1 != '/')
            {
                cout << "Неверный формат дроби номер: " << nomer << ". Введите заново эту дробь" << endl;
            }
        } while (d1 != '/');
    }
    void coutfraction()
    {cout << nominator << "/" << denominator << endl;}
    void summfraction(fraction, fraction, char);
    void lowterms();
};
void fraction::lowterms() // сокращение дроби
{
    long tnum, tden, temp, gcd;
    tnum = labs(nominator); 
    tden = labs(denominator); 
    if (tden == 0) 
    {
        cout << "Недопустимый знаменатель!"; exit(1);
    }
    else if (tnum == 0) // проверка числителя на 0
    {
        nominator = 0; denominator = 1; return;
    }
    // нахождение наибольшего общего делителя
    while (tnum != 0)
    {
        if (tnum < tden) // если числитель больше знаменателя,
        {
            temp = tnum; tnum = tden; tden = temp;
        } // меняем их местами
        tnum = tnum - tden; // вычитание
    }
    gcd = tden; // делим числитель и знаменатель на
    nominator = nominator / gcd; // полученный наибольший общий делитель
    denominator = denominator / gcd;
}
int fraction::vsego = 0;
void fraction :: summfraction(fraction x1, fraction y1, char ch)
{
    switch (ch)
    {
        case '+':  nominator = (x1.nominator * y1.denominator + x1.denominator * y1.nominator);
            denominator = (x1.denominator * y1.denominator);
            break;
        case '-': nominator = (x1.nominator * y1.denominator -x1.denominator * y1.nominator);
            denominator = (x1.denominator * y1.denominator);
            break;
        case '*': 
            nominator = (x1.nominator * y1.nominator);
            denominator = (x1.denominator * y1.denominator);
            break;
        case '/': 
            nominator = x1.nominator * y1.denominator;
            denominator = x1.denominator * y1.nominator;
            break;
    }
}
int main()
{
    setlocale(0, "Rus");
    fraction x, y, z;
    char ch;
    do {
        cout << "Введите первый операнд, затем знак операции и второй операнд: ";
        x.cinfraction();
       do{
        cin >> ch;
        if (ch != '/' && ch != '+' && ch != '-' && ch != '*')
            cout << "Неверный знак операции! Введите заново знак операции";
    } while (ch != '/' && ch!= '+' && ch!= '-' && ch!= '*');
        y.cinfraction();
        z.summfraction(x, y, ch);
        z.lowterms();
        cout << endl << "Результат равен: " << endl;
        z.coutfraction();
        cout << "Повторить?";
        cin >> ch;
    } while (ch != 'n');
}
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
30.12.2019, 12:40
Ответы с готовыми решениями:

Калькулятор дробей
Учусь программировать на C++, в данное время на мобильном компиляторе &quot;Cxx IDE for android&quot;. С утра хотел написать свой калькулятор...

Калькулятор для дробей
Написать программу калькулятор для дробей,с помощью цикла for.Пользователь выбирает одной из действий: сумма,вычитание,умножение,деление. ...

Калькулятор для дробей
Задача: Создать класс Fraction, который будет описывать дробь (числитель и знаменатель). Методы класса следующие: Farction Add (const...

8
Злостный нарушитель
 Аватар для Verevkin
10347 / 5765 / 1271
Регистрация: 12.03.2015
Сообщений: 26,624
30.12.2019, 13:06
Цитата Сообщение от pavellancov Посмотреть сообщение
Помогите, пожалуйста.
Научись юзать отладчик. Он предназначен как раз для решения таких проблем.
1
 Аватар для nyaka_wai
85 / 34 / 20
Регистрация: 15.12.2019
Сообщений: 89
30.12.2019, 15:07
У вас остается мусор в потоке cin после ошибок, можете очистить его вручную - добавьте это в конце своих циклов do while, где фигурирует cin

C++
1
cin.clear(); cin.ignore(cin.rdbuf()->in_avail());
Я проверил. После добавления этого код ошибок больше нет
2
0 / 0 / 0
Регистрация: 17.11.2019
Сообщений: 6
30.12.2019, 21:01  [ТС]
Спасибо за советы)
Попробую найти с помощью отладчика проблему

Добавлено через 49 минут
А почему этот мусор возникает? Да, это действительно помогает, но я так и не понял собственной ошибки на будущее. С отладчиком вожусь уже часа два, смотрю всякие видосы на ютубе как с ним работать и пытаюсь найти свою ошибку через него. Либо я не очень понимаю куда смотреть в этом отладчике в моем конкретном случае, чтобы обнаружить ошибку, либо обнаружить ее не так легко. Ну там значения изменяются, да, я вижу как они изменяются поэтапно, но почему операция син не выполняется все равно не понял. Я пока продолжаю изучать отладчик, но если подскажите, то буду благодарен.
0
653 / 466 / 183
Регистрация: 23.04.2019
Сообщений: 1,987
30.12.2019, 21:06
Скорее всего там символы по типу перехода на новую строку
0
 Аватар для nyaka_wai
85 / 34 / 20
Регистрация: 15.12.2019
Сообщений: 89
30.12.2019, 22:35
Лучший ответ Сообщение было отмечено pavellancov как решение

Решение

Цитата Сообщение от pavellancov Посмотреть сообщение
Спасибо за советы)
Попробую найти с помощью отладчика проблему

Добавлено через 49 минут
А почему этот мусор возникает? Да, это действительно помогает, но я так и не понял собственной ошибки на будущее. С отладчиком вожусь уже часа два, смотрю всякие видосы на ютубе как с ним работать и пытаюсь найти свою ошибку через него. Либо я не очень понимаю куда смотреть в этом отладчике в моем конкретном случае, чтобы обнаружить ошибку, либо обнаружить ее не так легко. Ну там значения изменяются, да, я вижу как они изменяются поэтапно, но почему операция син не выполняется все равно не понял. Я пока продолжаю изучать отладчик, но если подскажите, то буду благодарен.
Это возникает из-за твоего цикла ,while, когда ты несколько раз подряд вводишь значения в одну и ту же переменную

Добавлено через 57 минут
Если твой cin не проходит заданный тобой паттерн цифра/цифра, то он флагается ошибками cin.bad и сin.fail, которые созданы для анализа ошибки ввода. В этом случае поток ввода не очищается самостоятельно и при следующем вызове cin уже имеет мусор с прошлого вызова, из-за чего происходит завершение метода даже до того, как пользователю предоставляется возможность ввести что-то самостоятельно.

Добавлено через 3 минуты
Вот тебе пример функции безопасного ввода чисел, где после каждого cin выполняется проверка корректности и очищается мусор.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
template <class TXT, class NUM> void input_s(NUM&, TXT, float = NULL, float = NULL, TXT = "Некорректный ввод.\n"); //прототип функции
...
template <class TXT, class NUM> void input_s(NUM& arg, TXT message, float  min, float  max, TXT message_error)  //функция безопасного ввода int, float, double
{
    NUM _buffer; bool error = true;
    {
        while (error)    // выполнение ввода до тех пор, пока будут ошибки
        {
            cout << message; cin >> _buffer;    // выводим наше сообщение, вводим что-то с клавиатуры
            error = (cin.fail() || cin.bad());  // проверяем наличие ошибок для данного типа 
            cin.clear(); cin.ignore(cin.rdbuf()->in_avail());   // очищаем поток от мусора, сбрасываем ошибки 
            if (!error && !(min == NULL && max == NULL))        // проверяем входимость в указанный интервал 
                error = _buffer < min || _buffer > max;         // (только если min и max указаны в качестве дополнительных аргументов)
            if (error) cout << message_error;   // очищаем поток от мусора, выводим сообщение об ошибке
                else arg = _buffer;;            // если ошибок нет, возвращаем безопасное значение
        }
    }
}
0
0 / 0 / 0
Регистрация: 17.11.2019
Сообщений: 6
30.12.2019, 22:52  [ТС]
о, я, кажется, осознал, спасибо! Еще вот эта статья помогла https://ravesli.com/urok-72-ob... z-std-cin/ (пускай будет, вдруг кому еще пригодится).
0
 Аватар для nyaka_wai
85 / 34 / 20
Регистрация: 15.12.2019
Сообщений: 89
30.12.2019, 23:37
Цитата Сообщение от pavellancov Посмотреть сообщение
о, я, кажется, осознал, спасибо! Еще вот эта статья помогла https://ravesli.com/urok-72-ob... z-std-cin/ (пускай будет, вдруг кому еще пригодится).
Помнится, когда в универе учили Борланд Паскаль, - проверка на дурака была одной из первых вещей, которые выдалбливали в наши головешки)
0
0 / 0 / 0
Регистрация: 28.06.2019
Сообщений: 15
19.09.2020, 16:29
Может быть, кому-то пригодится калькулятор смешанных дробей https://your-online.ru/math-calculators/fractions
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
19.09.2020, 16:29
Помогаю со студенческими работами здесь

Калькулятор рациональных дробей
Первая программа принимает от пользователя три строки, (первая и третья строки – это правильные рациональные или десятичные дроби вида ...

Калькулятор для дробей
Создать калькулятор, который выполняет 4 арифметичуские действия над дробями. Пользователь должен сначало ввести первый операнд, знак...

Калькулятор дробей - Перегрузка операторов
Мне дали ошибки на мою программу хочу спросить как правильно их исправить? Не нужно дублировать код. Не нужно перемножать...

Калькулятор дробей с помощью классов
Добрый день, мне кажется я тут уже видел программку калькулятор дробей, где нужно создать class fraction для подсчета суммы, разности,...

Усовершенствованный калькулятор рациональных дробей
Добавил операторы сравнения и равно, всё скомпилировалось, ровно работает, при добавлении &lt;=,&gt;=,!= в отдельных case, всё...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 19.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru