i new to programming and we are required to create a program that dont exit when the user inputs the wrong input, but i only learned the basics so far.. i already solved when the number is above and below 100 but when the user accidentally inserted a non integer it will go into a error loop. btw this is an average calculator.
#include <iostream>
using namespace std;
int main()
{
int num[100];
int n;
double sum, average;
cout << "how many numbers will you input?: ";
cin >> n;
while ( n > 100 || n <= 0 )
{
cout << "Error! number should in range of (1 to 100) only." << endl;
cout << "Enter the number again: ";
cin >> n;
}
for ( int i = 0; i < n; i )
{
cout << i 1 << ". Enter number: ";
cin >> num[i];
sum = num[i];
}
average = sum / n;
cout << "Average = " << average;
}
CodePudding user response:
If std::istream::operator >>
fails, it will set failbit. Therefore, you should check failbit
(for example by calling std::cin.fail()
) to see whether the conversion was successful, before using the result of the conversion.
If the conversion fails due to bad input, then the next call to std::istream::operator >>
will automatically fail due to failbit
being set. Therefore, if you want to attempt input again, you will first have to clear failbit
, by using the function std::cin.clear()
.
Also, you will have to discard the bad input that caused the conversion to fail, because otherwise, the next time you call std::istream::operator >>
, the conversion will fail again for the same reason. In order to clear the bad input, you can use std::cin.ignore()
, like this:
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
However, I don't recommend that you use std::istream::operator >>
, because its behavior not always intuitive. For example, it
- does not always read a whole line of input and
- accepts
6abc
as valid input for the number6
.
In my experience, if you want proper input validation of integer input, it is usually better to write your own function that reads a whole line of input using std::getline
and converts it with std::stoi
. If the input is invalid, then the function should automatically reprompt the user.
In my example below, I am calling this function get_int_from_user
.
If you want to additionally ensure that the input is in a certain range, then you can call the function get_int_from_user
in an infinite loop, and break out of that loop once you determine that the input is valid.
#include <iostream>
#include <string>
#include <sstream>
int get_int_from_user( const std::string& prompt );
int main()
{
int nums[100];
int n;
double sum;
//repeat loop forever, until input is good
for (;;) //equivalent to while(true)
{
n = get_int_from_user( "How many numbers will you input? " );
if ( 1 <= n && n <= 100 )
//input is good
break;
std::cout << "Error! Number should in range of (1 to 100) only.\n";
}
//read one number per loop iteration
for( int i = 0; i < n; i )
{
std::ostringstream prompt;
prompt << "Enter number #" << i 1 << ": ";
nums[i] = get_int_from_user( prompt.str() );
sum = nums[i];
}
std::cout << "Average: " << sum / n << '\n';
}
int get_int_from_user( const std::string& prompt )
{
std::string line;
std::size_t pos;
int i;
//repeat forever, until an explicit return statement or an
//exception is thrown
for (;;) //equivalent to while(true)
{
//prompt user for input
std::cout << prompt;
//attempt to read one line of input from user
if ( !std::getline( std::cin, line ) )
{
throw std::runtime_error( "unexpected input error!\n" );
}
//attempt to convert string to integer
try
{
i = std::stoi( line, &pos );
}
catch ( std::invalid_argument& )
{
std::cout << "Unable to convert input to number, try again!\n";
continue;
}
catch ( std::out_of_range& )
{
std::cout << "Out of range error, try again!\n";
continue;
}
//The remainder of the line is only allowed to contain
//whitespace characters. The presence of any other
//characters should cause the entire input to get rejected.
//That way, input such as "6sdfj23jlj" will get rejected,
//but input with trailing whitespace will still be accepted
//(just like input with leading whitespace is accepted by
//the function std::stoi).
for ( ; pos < line.length(); pos )
{
if ( !std::isspace( static_cast<unsigned char>(line[pos]) ) )
{
std::cout << "Invalid character found, try again!\n";
//we cannot use "continue" here, because that would
//continue to the next iteration of the innermost
//loop, but we want to continue to the next iteration
//of the outer loop
goto continue_outer_loop;
}
}
//input is valid
return i;
continue_outer_loop:
continue;
}
}
This program has the following behavior:
How many numbers will you input? 200
Error! Number should in range of (1 to 100) only.
How many numbers will you input? -31
Error! Number should in range of (1 to 100) only.
How many numbers will you input? 4
Enter number #1: 1
Enter number #2: 2
Enter number #3: 6abc
Invalid character found, try again!
Enter number #3: five
Unable to convert input to number, try again!
Enter number #3: 3
Enter number #4: 4
Average: 2.5
CodePudding user response:
#include <iostream>
using namespace std;
int avg(int sum, int n)
{
int average;
average = sum/n;
cout<<"Avg = "<<average;
}
int main()
{
int n;
int num[n];
int sum;
cout << "how many numbers will you input?: ";
cin >> n;
while(n>100||n<=0)
{
cout << "Error! number should in range of (1 to 100) only." << endl;
cout << "Enter the number again: ";
cin >> n;
}
for(int i = 0; i < n; i)
{
cout << i 1 << "Enter number: ";
cin >> num[i];
if(!cin)
{
cout << "Wrong Choice. " << endl;
cin.clear();
cin.ignore(256, '\n');//to ignore number not in range of integer
/*we do this because in case of wrong input this will run for 1 of the i values of loop so in case of 5
input if 1 is wrong it will take avg of 4 only b/c one was wrong so in order to take 5 input sum increment n*/
n ;
continue;
}
else
{
sum = num[i];
}
}
cout<<"Sum = "<<sum<<endl;
avg(sum,n);
}