Простой средний расчет - PullRequest
1 голос
/ 20 мая 2010

Я пытаюсь написать программу, вычисляющую среднее значение заданных чисел, хранящихся в массиве. Количество чисел должно быть не более 100, и пользователь должен вводить их, пока не будет задана переменная! Int:

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

Почему после указания char он выводит мне «Give n number:» для всех пустых ячеек моего массива? Он должен заканчиваться и использовать только заданные числа.

Ответы [ 8 ]

5 голосов
/ 20 мая 2010

Вы используете isdigit здесь неправильно - он используется для проверки, является ли char числовым или нет - вы не можете использовать его для проверки типа int.

Возможно, вы захотите использовать специальное значение для завершения ввода, например, -1 или -999. Если это неприемлемо, тогда вам нужно прочитать строку, а не целое число, а затем решить, является ли она числовой или нет.

1 голос
/ 20 мая 2010
#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;
}
1 голос
/ 20 мая 2010

isdigit проверяет, является ли символ цифрой. Тест достигается только после присвоения 0 номеру, а 0 - это контрольный код, а не цифра, поэтому isdigit(0) всегда ложно, и поэтому ваше условие while всегда верно.

 ...
       number=0;
 ...
} while( !isdigit(number) );      

Вместо этого протестируйте входной поток, чтобы определить, успешно ли он прочитал значение.

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;
}
1 голос
/ 20 мая 2010

Помимо неправильного использования isdigit (), который вместо этого должен использовать какой-то часовой механизм, нет необходимости хранить числа в массиве.Для расчета среднего достаточно промежуточной суммы и количества чисел.

Кроме того, должна быть проверка на ввод нулевых элементов, чтобы предотвратить ошибку деления на ноль.

0 голосов
/ 20 мая 2010

isdigit сообщит вам, представляет ли код символа набора символов одну из цифр 0 - 9.

Поэтому (я предполагаю, что вы используете ASCII), вы можете просто использовать символ и проверить его диапазон кода ASCII:

    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; 

Вы также можете использовать cin.getline и atoi или 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; 

Есть и другие методы, которые вы можете использовать, однако они должны дать вам некоторые идеи.

0 голосов
/ 20 мая 2010

Вы можете использовать lexical_cast от наддува. Вы читаете ввод в строку, и lexical_cast проверит, может ли он быть преобразован в строку. Это также гарантирует, что ваша строка не будет слишком длинной для преобразования, если это отрицательное число или число вообще.

#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;
}
0 голосов
/ 20 мая 2010

Есть несколько проблем с вашим кодом:

cin >> number;

Вы не проверяете, не завершилась ли операция извлечения потока. Простой способ сделать это - использовать оператор преобразования operator void*():

if (cin >> number)
  ... operation succeeded ...

Приведенный выше код эквивалентен проверке failbit и badbit.

Использование isdigit() также неверно, так как вы передаете число (например, 1234 вместо символа (например, 'z'). Независимо от того, добавляется операция извлечения потока проверка отказа устраняет необходимость такой проверки на основе цифр.

0 голосов
/ 20 мая 2010

Лучший способ обнаружения ввода не-числа - это проверить состояние cin после считывания значения:

// ...
if (cin >> number)
{
  tab[n++] = number;
}
else
{
  break;  // break out of loop
}

Также помните, что могут быть другие причины, по которым ввод не удался, кроме не правильного ввода номера.

...