Reputation: 65
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;
}
Upvotes: 2
Views: 671
Reputation: 10750
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:
Upvotes: 0
Reputation: 73542
You have three options:
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) std::stof()
, and check that all characters of the string where successfully readHere 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;
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;
}
Upvotes: 1