1

我正在尝试编写程序计算存储在数组中的给定数字的平均值。数字的数量不应超过 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 后,它会为我的数组的所有空单元格打印“给 n 号:”?它应该结束并只使用给定的数字。

4

8 回答 8

5

您在isdigit这里使用不正确 - 它用于测试 a 是否char为数字 - 您不能使用它来测试 int。

您可能需要考虑使用特殊值来终止输入,例如-1or -999。如果这不可接受,那么您需要读取字符串而不是 int,然后确定它是否为数字。

于 2010-05-19T21:32:13.483 回答
1

除了滥用 isdigit() 而应该使用一些哨兵机制之外,没有必要将数字存储在数组中。运行总和和数字计数足以计算平均值。

此外,应该检查输入的零元素,以防止除以零错误。

于 2010-05-19T21:41:56.843 回答
1

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;
}
于 2010-05-19T21:49:26.967 回答
1
#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;
}
于 2010-05-19T21:52:52.730 回答
0

检测非数字输入的更好方法是cin在读取值后测试状态:

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

还要记住,除了没有输入有效数字之外,输入失败可能还有其他原因。

于 2010-05-19T21:43:35.357 回答
0

您的代码存在一些问题:

cin >> number;

您不检查流提取操作是否失败。一种简单的方法是利用operator void*()转换运算符:

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

上面的代码相当于检查failbitand badbit

您的使用isdigit()也是错误的,因为您传递了一个数字(例如1234,而不是一个字符(例如'z')。无论如何,添加流提取操作失败检查消除了对这种基于数字的检查的需要。

于 2010-05-19T21:48:40.837 回答
0

你可以使用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;
}
于 2010-05-19T22:02:23.223 回答
0

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.getlineand atoior 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; 

您可以使用其他方法,但是,这些方法应该会给您一些想法。

于 2010-05-19T22:08:07.560 回答