Помогите доработать программу.

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

#include <iostream>
using namespace std;
bool diapozon(double otv)
{
    if (otv <= 100 && otv >= -100)
    {
    return false;
}
    else
    {
    return true;
}
}
int main()
{
    setlocale (0, "");
short unsigned int i = 1;   
long double a, b, e;
char c;
while (i == 1)
{
cout << "Введите первое число(в диапазоне от 100 до -100)" << endl;
cin >> a;
if (!diapozon(a))
{
cout << "Введите второе число(в диапазоне от 100 до -100)" << endl;
cin >> b;
if (!diapozon(b))
{
cout << "Введите знак действия" << endl;
cin >> c; 
if (c=='+')
{
 e = a + b;
 cout << "Ответ: " << e << endl; 
        cout << "______________________________________________________________________" << endl;
}
else if (c=='-')
{
 e = a - b;
 cout << "Ответ: " << e << endl;
    cout << "______________________________________________________________________" << endl;
} 
else if (c=='*')
{
 e = a * b;
 cout << "Ответ: " << e << endl;
    cout << "______________________________________________________________________" << endl;
}
else if (c=='/')
{
 e = a / b;
 cout << "Ответ: " << e << endl;
    cout << "______________________________________________________________________" << endl;
}
else
{
    cout << "Ошибка!!!" << endl;
    cout << "______________________________________________________________________" << endl;
}
}
else
{
    cout << "Ошибка!!" << endl;
    cout << "______________________________________________________________________" << endl;
}
}
else
{
    cout << "Ошибка!" << endl;
    cout << "______________________________________________________________________" << endl;
}
}
return 0;
}

Можно так (на примере считывания элементов массива, взято здесь):

// инициализация массива вводом из cin
bool fail = false;
for (unsigned int i = 0; i < ARRSIZE; i++) {
    do {
        fail = false;
        cout << "Введите значение для элемента массива " << i << ": ";
        cin >> ary[i];
        if (cin.fail()) {
            cout << "*** Введено некорректное значение. Повторите ввод." << endl;
            fail = true;
        }
        cin.clear();
        cin.ignore();
    } while (fail);

}

Можно изобрести велосипед и считывать строкой, переводя её в число в случае правильного ввода.

Vova_vb, прежде чем помочь, хочу спросить, когда завершается ваша программа? :)

Ваш калькулятор, с учетом всех проверок, а именно:
— проверка выхода за пределы заданного диапазона;
— проверка на ввод некорректного числа;
— проверка на ввод некорректного арифметического знака;
— проверка деления на нуль;
— проверка на выход из программы;
можно организовать так:

#include <iostream>
#include <cstdlib>    // for system

double getNumber();
bool checkRange(double num);
bool checkSign(char sign);
double getAnswer(double fNum, double sNum, char sign);
bool isQuit(char choice);

int main()
{
    double firstVal, secondVal;
    char sign, choice;

    do {        
        do {
            do {
                std::cout << "Enter the first value in a range from -100 to 100: ";
                firstVal = getNumber();
            } while (!checkRange(firstVal));

            std::cin.sync();

            do {
                std::cout << "Enter an arithmetic operator (+, -, *, /): ";
                std::cin >> sign;

                std::cin.sync();

            } while (!checkSign(sign));

            do {
                std::cout << "Enter the second value in a range from -100 to 100: ";
                secondVal = getNumber();
            } while (!checkRange(secondVal));

            std::cin.sync();

            if (!secondVal && '/' == sign) {
                std::cout << "Division by zero is disable.\n\n";
            }
        } while (!secondVal && '/' == sign);

        std::cout << "\n" << firstVal << " " << sign << " " << secondVal << " = " << getAnswer(firstVal, secondVal, sign) << '\n';

        std::cout << "\nContinue >> any key; Exit >> q \nYour choice: ";
        std::cin >> choice;

        std::cin.sync();

        system("cls");

    } while (!isQuit(choice));

    std::cout << "\nBye!\n";

    return 0;
}

double getNumber()
{
    double num;

    while (!(std::cin >> num).get()) {
        std::cin.clear();
        while (std::cin.get() != '\n')
            continue;
        std::cout << "Make a correct input >> ";
    }

    return num;
}

bool checkRange(double num)
{
    if (num <= 100 && num >= -100) {
        return true;
    }
    else {
        return false;
    }
}

bool checkSign(char sign)
{
    if ('+' == sign || '-' == sign || '*' == sign || '/' == sign) {
        return true;
    }
    else {
        return false;
    }
}

double getAnswer(double fNum, double sNum, char sign)
{
    double answer;

    switch (sign) {
        case '+': answer = fNum + sNum; break;
        case '-': answer = fNum - sNum; break;
        case '*': answer = fNum * sNum; break;
        case '/': answer = fNum / sNum; break;
        default: std::cout << "Wrong operation.\n"; break;
    }

    return answer;
}

bool isQuit(char choice)
{
    if ('q' == choice) {
        return true;
    }
    else {
        return false;
    }
}

с учетом всех проверок

Да ладно?

Тест под линуксом: http://youtu.be/H3kfYWnNpTQ

А знаете почему так происходит? Потому что std::istream::sync

имеет особенность:

Specifics of the operation depend on the particular implementation of the stream buffer object associated to the stream.

Я согласен с вами, Croessmah. Здесь много подводных камней с обработкой ввода. Попробуйте протестировать под Linux следующий код.

#include <iostream>
#include <cstdlib>    // for system

double getNumber();
char getChar();
bool checkRange(double num);
bool checkSign(char sign);
double getAnswer(double fNum, double sNum, char sign);
bool isQuit(char choice);

int main()
{
    double firstVal, secondVal;
    char sign, choice;

    do {
        do {
            do {
                std::cout << "Enter the first value in a range from -100 to 100: ";
                firstVal = getNumber();
            } while (!checkRange(firstVal));

            do {
                std::cout << "Enter an arithmetic operator (+, -, *, /): ";
                sign = getChar();

            } while (!checkSign(sign));

            do {
                std::cout << "Enter the second value in a range from -100 to 100: ";
                secondVal = getNumber();
            } while (!checkRange(secondVal));

            if (!secondVal && '/' == sign) {
                std::cout << "Division by zero is disable.\n\n";
            }
        } while (!secondVal && '/' == sign);

        std::cout << "\n" << firstVal << " " << sign << " " << secondVal << " = " << getAnswer(firstVal, secondVal, sign) << '\n';

        std::cout << "\nContinue >> any key; Exit >> q \nYour choice: ";
        choice = getChar();

        system("cls");

    } while (!isQuit(choice));

    std::cout << "\nBye!\n";

    return 0;
}

double getNumber()
{
    double num;

    while (!(std::cin >> num)) {
        std::cin.clear();
        while (std::cin.get() != '\n') {
            continue;
        }
        std::cout << "Make a correct input >> ";
    }

    while (std::cin.get() != '\n') {
        continue;
    }

    return num;
}

char getChar()
{
    char ch;

    std::cin >> ch;

    std::cin.clear();

    while (std::cin.get() != '\n') {
        continue;
    }

    return ch;
}

bool checkRange(double num)
{
    if (num <= 100 && num >= -100) {
        return true;
    }
    else {
        return false;
    }
}

bool checkSign(char sign)
{
    if ('+' == sign || '-' == sign || '*' == sign || '/' == sign) {
        return true;
    }
    else {
        return false;
    }
}

double getAnswer(double fNum, double sNum, char sign)
{
    double answer;

    switch (sign) {
        case '+': answer = fNum + sNum; break;
        case '-': answer = fNum - sNum; break;
        case '*': answer = fNum * sNum; break;
        case '/': answer = fNum / sNum; break;
        default: std::cout << "Wrong operation.\n"; break;
    }

    return answer;
}

bool isQuit(char choice)
{
    if ('q' == choice) {
        return true;
    }
    else {
        return false;
    }
}

Нашел свой вариант решения проблемы.

 #include <iostream>
using namespace std;

bool a ( double b )
{
    if (b >= 1)
    {
        return true;
    }
    else
    {
        return false;
    }
}
bool des ( char z )
{
    if (z == '+')
    {
        return true;
    }
    else if (z == '-')
    {
        return true;
    }
    else if (z == '*')
    {
        return true;
    }
    else if (z == '/')
    {
        return true;
    }
    else
    {
        return false;
    }
}
double umn(double d, double s)
{
    double c = 0;
    c = d * s;
    return c;
}

double del(double d, double s)
{
    double c = 0;
    c = d / s;
    return c;
}

double sum(double d, double s)
{
    double c = 0;
    c = d + s;
    return c;
}

double vch(double d, double s)
{
    double c = 0;
    c = d - s;
    return c;
}

int main()
{
    setlocale (0, "");
    int s, v, b;
    char cum;
    bool c;
    cin >> s;
    c = a(s);
    if (c == 1)
    {
      c = 0;
      cin >> cum;
      c = des(cum);
      if (c == 1)
      {
      cin >> v;
      c = a(v);
      if(c != 1)
      {
        cout << "error" << endl;
      }
      else if(c == 1)
      {
        if (cum == '+')
        {
            b = sum(s, v);
            cout << b;
        }
        else if (cum == '-')
        {
            b = vch(s, v);
                cout << b;
        }
        else if (cum == '/')
        {
            b = del(s, v);
                cout << b;
        }
        else if (cum == '*')
        {
            b = umn(s, v);
                cout << b;
        }
      }
     }
     else if (c == 0)
     {
            cout << "error" << endl;
     }
    }
    else if(c == 0)
    {
        cout << "error" << endl;
    }
    return 0;
}

По моему, Vova_vb, это не решение старой проблемы, а начало новой.
Интересно, через две недели, вы сами поймете, что написали?
Присваиваете значение переменной double переменной типа int, в итоге потеря данных.

double del(double d, double s)
{
    double c = 0;
    c = d / s;
    return c;
}

/ ...

int s, v, b;

/ ...

else if (cum == '/')
    {
        b = del(s, v);
            cout << b;
    }

Еще вопрос, а ваша программа делить на отрицательные числа умеет?

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.

Ответить

Вы можете использовать разметку markdown для оформления комментариев и постов. Используйте функцию предпросмотра для проверки корректности разметки.

Пожалуйста, оформляйте исходный код в соответствии с правилами разметки. Для того, чтобы вставить код в комментарий, скопируйте его в текстовое поле ниже, после чего выделите то, что скопировали и нажмите кнопку «код» в панели инструментов. Иначе ваш код может принять нечитаемый вид.

Либо производите оформление кода вручную, следующим образом:

``` #include <iostream> using namespace std; int main() { // ... } ```

Предпросмотр сообщения

Ваше сообщение пусто.