Попытка проверить ввод в C ++ - PullRequest
3 голосов
/ 26 апреля 2019

Идея этого кода в c ++ состоит в том, чтобы вычислить сумму всех введенных чисел. Когда пользователь вводит 0, программа должна остановиться. Эта часть кода работает, как я и предполагал, но я хотел бы включить вариант, который распознает, что введен символ, отличный от числа с плавающей запятой, игнорирует его в вычислениях и позволяет пользователю продолжать ввод чисел с плавающей запятой. В настоящий момент ввод чего-либо еще, кроме числа с плавающей запятой, останавливает программу.

Я знаю, что есть условие "if (! (Cin >> numb))", я пытался проанализировать его в разных местах кода, но я не могу понять, как заставить программу игнорировать эти недопустимые значения. входы. Буду очень признателен за любую помощь.

#include <iostream>
#include <stdlib.h>

using namespace std;

float numb; float sum=0;

int main()
{
    cout << "This app calculates the sum of all entered numbers." << endl;
    cout << "To stop the program, enter 0." << endl << endl;
    cout << "Enter the first number: ";
    cin >> numb;

    while(true)
    {
        sum += numb;

        if (numb!=0)
        {
            cout << "Sum equals: " << sum << endl << endl;
            cout << "Enter another number: ";
            cin >> numb;
        }
        else
        {
            cout << "Sum equals: " << sum << endl << endl;
            cout << "Entered 0." << endl;
            cout << "Press Enter to terminate the app." << endl;
            exit(0);
        }
    }
    return 0;
}

Ответы [ 2 ]

1 голос
/ 27 апреля 2019

У вас есть три варианта:

  • методом проб и ошибок: попробуйте прочитать число с плавающей точкой, а в случае ошибки сбросьте флаг ошибки, проигнорируйте неверный ввод и повторите чтение.Проблема в том, что вы не знаете, сколько входных данных нужно игнорировать.
  • читать строки: читать строки, разделенные пробелом, пытаться преобразовать строку, используя stringstream, и просто игнорировать полную строку в случае ошибки.Проблема заключается в том, что если ввод начинается с допустимого числа с плавающей запятой, но затем содержит недопустимые символы (например, 12X4), недопустимая часть будет игнорироваться (например, X4)
  • управляющий синтаксический анализ: чтение строк, разделенных пробелом, попытаться преобразоватьстроку, используя std::stof(), и убедитесь, что все символы строки, где успешно прочитано

Здесь второй подход, со слегка реструктурированным циклом, так что запись 0 приведетчтобы выйти из цикла, а не из полной программы:

string input;  
while(cin >> input)
{
    stringstream sst(input); 
    if (sst>>numb) {
        sum += numb;
        cout << "Sum equals: " << sum << endl << endl;
        if (numb==0)
        {
            cout << "Entered 0." << endl;
            break;  // exits the while loop 
        }
        cout << "Enter another number: ";
    }
    else 
    {
        cout << "Ignored entry "<<input<<endl; 
    }
}
cout << "Press Enter to terminate the app." << endl;

Демонстрация в Интернете

Если вы предпочитаете более точный анализ, рассмотрите что-то вроде:

size_t pos=0; 
float xx = stof(input, &pos );
if (pos!=input.size()) {
    cout << "error: invalid trailing characters" <<endl; 
}
0 голосов
/ 27 апреля 2019

Вы должны очистить бит после сбоя чтения.После этого вы можете прочитать недопустимый материал в строку (которую вы просто игнорируете).Эта функция будет считывать значения и добавлять их до тех пор, пока не встретит 0 или конец входного потока.

int calc_sum_from_input(std::istream& stream) {
    int sum = 0; 
    // If it couldn't read a value, we just read the thing into here
    std::string _ignored;
    while(stream) // Checks if the stream has more stuff to read
    {
        int value;
        if(stream >> value) 
        {
            if(value == 0) // Exit if it read the value 0
                break;
            else 
                sum += value; // Otherwise update the sum
        }
        else {
            // Clear the failbit
            stream.clear(); 
            // Read ignored thing
            stream >> _ignored;
        }
    }
    return sum; 
}

Логика в основном такова:

  • установить начальную сумму на 0
  • проверить, есть ли что читать
    • , если естьпопробуйте прочитать значение
    • в случае успеха, проверьте значение 0
      • если оно равно 0, выйдите и верните сумму
      • в противном случае добавьте значение к сумме
    • в противном случае очистите бит неудачи (чтобы вы могли снова прочитать материал) и прочитайте неверное значение в строку (которая игнорируется)
  • в противном случае вернуть значение
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...