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 を指定した後、配列のすべての空のセルに対して「Give n number:」と表示されるのはなぜですか? 指定された数字のみを終了して使用する必要があります。

4

8 に答える 8

5

isdigitここでは誤って使用していcharます-aが数値であるかどうかをテストするために使用されます-intをテストするために使用することはできません。

おそらく、-1またはなど、入力を終了するために特別な値を使用することを検討する必要があり-999ます。それが受け入れられない場合は、intではなく文字列を読み込んでから、数値かどうかを判断する必要があります。

于 2010-05-19T21:32:13.483 に答える
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 に答える
1

isdigit文字が数字かどうかをテストします。テストは、数値に 0 を割り当てた後にのみ到達します。0 は数字ではなく制御コードであるため、isdigit(0)常に false であり、while 条件は常に true です。

 ...
       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

代わりにセンチネルメカニズムを使用する必要がある isdigit() の誤用に加えて、数値を配列に格納する必要はありません。平均を計算するには、現在の合計と数のカウントで十分です。

また、ゼロ除算エラーを防ぐために、ゼロ要素が入力されているかどうかをチェックする必要があります。

于 2010-05-19T21:41:56.843 に答える
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.getlineandatoiまたは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 に答える
0

コードにはいくつかの問題があります。

cin >> number;

ストリーム抽出操作が失敗したかどうかを確認しません。これを行う簡単な方法は、operator void*()変換演算子を活用することです。

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

上記のコードは、 および をチェックすることfailbitと同じbadbitです。

の使用法はisdigit()、数字を渡すという点でも間違っています (たとえば1234、文字の代わりに (たとえば'z')。とにかく、ストリーム抽出操作の失敗チェックを追加すると、そのような数字ベースのチェックが不要になります。

于 2010-05-19T21:48:40.837 に答える
0

cin数値以外の入力を検出するためのより良い方法は、値を読み取った後の状態をテストすることです。

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

また、有効な数値が入力されていない以外にも、入力が失敗した理由が他にある可能性があることに注意してください。

于 2010-05-19T21:43:35.357 に答える