开发者

Simple average calculation

开发者 https://www.devze.com 2022-12-30 17:59 出处:网络
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 :

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.


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.


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


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.


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


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.


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.


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


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消