Reputation: 123
I'm trying to write program calculating average of given numbers stored in an array. Amount of numbers should be not more than 100, and user should input them until a !int variable is given :
#include <iostream>
#include <conio.h>
using namespace std;
double average(int tab[], int i){
int sum=0;
for(int j=0; j<i; ++j){
sum+=tab[j];
}
return (double)sum/i;
}
int main()
{
int tab[100];
int n=0;
int number=0;
do {
if(n < 100){
cout << "Give " << n+1 << " number : ";
cin >> number;
tab[n]=number;
number=0;
++n;
}
else{
break;
}
} while( !isdigit(number) );
cout << average(tab, n) << endl;
getch();
return 0;
}
Why after giving char, it prints me 'Give n number:' for all empty cells of my array ? It should end and use only given numbers.
Upvotes: 1
Views: 3315
Reputation:
isdigit
will tell you if a character code of a character set represents one of the digits 0 - 9.
Therefore, (I'm assuming you are using ASCII), you could simply use a character and test its ASCII code range:
int tab[100];
int n = 0;
char c;
while (n++ < 100)
{
cout << "Give " << n << " number : ";
cin >> c;
if (c < 48 || c > 57)
break;
tab[n - 1] = c - 48;
}
cout << average(tab, n - 1) << endl;
getch();
return 0;
You could also use cin.getline
and atoi
or strtod
:
int tab[100];
int n=0;
int number=0;
char input[10];
while (n++ < 100)
{
cout << "Give " << n << " number : ";
memset(input, 0x00, 10);
cin.getline(input, 10);
number = atoi(input);
if (number > 0)
tab[n-1] = number;
else
break;
}
cout << average(tab, n-1) << endl;
getch();
return 0;
There are other methods you can use, however, these should give you some ideas.
Upvotes: 0
Reputation: 49311
isdigit
tests whether the character is a digit. The test is only reached following assigning 0 to number, and 0 is a control code, not a digit, so isdigit(0)
is always false, and so your while condition is always true.
...
number=0;
...
} while( !isdigit(number) );
Instead, test the input stream to determine whether it successfully read a value.
int main()
{
const size_t COUNT = 100;
int tab[COUNT];
size_t n;
cin.tie(&cout); // ensures cout flushed before cin read
// (not required if your runtime complies with that part of the standard)
for (n = 0; n < COUNT; ++n ) {
cout << "Give " << n+1 << " number : ";
cin >> tab[n];
if (!cin)
break;
}
if (n > 0) // average is undefined if n == 0
cout << average(tab, n) << endl;
return 0;
}
Upvotes: 1
Reputation: 14129
You could use lexical_cast
from boost. You read the input into a string and the lexical_cast will check if it can be converted into a string. This will also make sure that your string is not to long to be converted, if it is a negative number or a number at all.
#include <iostream>
#include <string>
#include <boost/lexical_cast.hpp>
using std::cout;
using std::cin;
using std::endl;
using std::string;
using boost::lexical_cast;
using boost::bad_lexical_cast;
double average(int tab[], int i){
int sum=0;
for(int j=0; j<i; ++j){
sum+=tab[j];
}
return (double)sum/i;
}
int main()
{
int tab[100]; //this is a fairly low level construct which might want to
// into a std::vector
string input;
int n;
try{
for (n = 0 ;n < 100; n++) {
cout << "Give " << n+1 << " number : ";
cin >> input; //read number into string
tab[n]= lexical_cast<int>(input); //conversion with lexical_cast
//if not possible exception is
//thrown
}
}
catch(bad_lexical_cast &){
cout << "not a number" << endl;
}
cout << average(tab, n) << endl;
return 0;
}
Upvotes: 0
Reputation: 137800
#include <iostream> // <conio.h> is nonstandard
using namespace std;
int main() {
long total = 0, cnt = 0, num;
while ( cerr << "Enter " << ++ cnt << " number" << endl, // use cerr for interaction
// use comma operator to produce a side effect in loop expression
cin >> num ) { // use Boolean value of (cin >> ...) to end loop on input failure
total += num; // just keep a running total
}
-- cnt; // cnt went one too far :(
cout << static_cast<double>( total ) / cnt << endl;
}
Upvotes: 1
Reputation: 3481
There are a few problems with your code:
cin >> number;
You don't check if the stream extraction operation failed. A simple way to do that is to leverage the operator void*()
conversion operator:
if (cin >> number)
... operation succeeded ...
The above code is equivalent to checking the failbit
and badbit
.
Your usage of isdigit()
is also wrong in that you're passing a number (e.g. 1234
of instead of a character (e.g. 'z'
). Regardless, adding a stream extraction operation failure check obviates the need for such a digit based check.
Upvotes: 0
Reputation: 57678
The better method for detecting the input of a non-number is to test the state of cin
after reading a value:
// ...
if (cin >> number)
{
tab[n++] = number;
}
else
{
break; // break out of loop
}
Also remember that there may be other reasons the input failed other than not inputting a valid number.
Upvotes: 0
Reputation: 57774
Besides the misuse of isdigit() which should instead use some sentinel mechanism, there's no need to store the numbers in an array. A running sum and a count of numbers is sufficient for calculating an average.
Also, there should be a check for zero elements entered to prevent a divide by zero error.
Upvotes: 1
Reputation: 212959
You're using isdigit
incorrectly here - it's used to test whether a char
is numeric or not - you can't use it to test an int.
You probably want to consider using a special value to terminate input, e.g. -1
or -999
. If that's not acceptable then you'll need to read in a string rather than an int and then decide whether it's numeric or not.
Upvotes: 5