Arhn - архитектура программирования

Попытка проверить ввод в С++

Идея этого кода на С++ состоит в том, чтобы вычислить сумму всех введенных чисел. Когда пользователь вводит 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;
}

  • Шаг 1. Проверка, подтверждающая, что cin >> numb успешно прочитал float if (cin >> numb) { use numb } else { clear error flag and discard bad data } 26.04.2019
  • На самом деле, вы на правильном пути. Посмотрите здесь, но следите за комментариями, предпочитающими максимальный размер stream_size... 26.04.2019

Ответы:


1

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

  • метод проб и ошибок: попробуйте прочитать число с плавающей запятой, а в случае ошибки снимите флаг ошибки, проигнорируйте неверный ввод и прочитайте снова. Проблема в том, что вы на самом деле не знаете, сколько входных данных следует игнорировать.
  • читать строки: читать строки, разделенные пробелами, пытаться преобразовать строку, используя 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; 
}
26.04.2019
  • Большое спасибо! Это именно то, что я искал! 27.04.2019

  • 2

    Вы должны очистить бит ошибки после неудачного чтения. После этого вы можете прочитать неверный материал в строку (которую вы просто игнорируете). Эта функция будет считывать значения и суммировать их, пока не встретит 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
    • check if there's stuff to read
      • if there is, try reading in a value
      • if successful, check if the value is 0
        • if it's 0, exit and return the sum
        • в противном случае добавьте значение к сумме
      • в противном случае очистите бит ошибки (чтобы вы могли снова прочитать что-то) и прочитайте неверное значение в строку (которое игнорируется)
    • в противном случае вернуть значение
    26.04.2019
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..