2

The idea behind this code in c++ is to calculate the sum of all the entered numbers. When the user enters 0, the program should stop. This part of the code is working as I intended, but I'd like to include a variant which recognizes that a character different than a float number has been entered, ignore it in the calculation and allow the user to continue entering float numbers. At the moment, entering anything else but a float number stops the program.

I know there's a "if (!(cin >> numb))" condition, I've tried parsing it in different places in the code, but I can't figure out how to force the program to ignore these invalid inputs. I would be very grateful for any help.

#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
    Step 1: Test to confirm that cin >> numb was successful in reading a float if (cin >> numb) { use numb } else { clear error flag and discard bad data } Commented Apr 26, 2019 at 20:52
  • Actually, you are on the right way. Have a look at here, but keep an eye on the comment preferring the stream_size maximum... Commented Apr 26, 2019 at 20:53

2 Answers 2

1

You have three options:

  • trial and error: try to read a float, and in case of error clear the error flag, ignore the bad input and read again. The problem is that you don't know really how many of the input is to be ignored.
  • read strings: read space delimited strings, try to convert the string using stringstream, and just ignore the full string in case of error. The problem is that if the input starts with a valid float but then contains invalid characters (e.g. 12X4), the invalid part will be ignored (e.g. X4)
  • control parsing: read space delimited strings, try to convert the string using std::stof(), and check that all characters of the string where successfully read

Here the second approach, with a slightly restructured loop, so that a 0 entry will lead to exiting the loop and not the full program:

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;

Online demo

If you prefer a more accurate parsing, consider something like:

size_t pos=0; 
float xx = stof(input, &pos );
if (pos!=input.size()) {
    cout << "error: invalid trailing characters" <<endl; 
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much! This is exactly what I was looking for!
0

You have to clear the failbit after a failed read. After that, you can read in the invalid stuff into a string (that you just ignore). This function will read in values and add them up until it encounters a 0 or the end of the input stream.

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; 
}

The logic is basically:

  • set the initial sum to 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
      • otherwise, add the value to the sum
    • otherwise, clear the failbit (so that you can read stuff in again) and read the bad value into a string (which gets ignored)
  • otherwise, return the value

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.