我正在尝试编写程序计算存储在数组中的给定数字的平均值。数量不应超过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:'?它应该结束并仅使用给定的数字。
答案 0 :(得分:5)
您在这里错误地使用isdigit
- 它用于测试char
是否为数字 - 您无法使用它来测试int。
您可能需要考虑使用特殊值来终止输入,例如-1
或-999
。如果这是不可接受的,那么你需要读取一个字符串而不是一个int,然后决定它是否是数字。
答案 1 :(得分:1)
除了误用isdigit()之外应该使用一些哨兵机制,不需要将数字存储在数组中。运行总和和数字计数足以计算平均值。
此外,应检查输入的零元素以防止除以零错误。
答案 2 :(得分:1)
isdigit
测试该字符是否为数字。只有在为0指定0后才能进行测试,而0是控制代码,而不是数字,因此isdigit(0)
始终为false,因此您的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;
}
答案 3 :(得分: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;
}
答案 4 :(得分:0)
检测非数字输入的更好方法是在读取值后测试cin
的状态:
// ...
if (cin >> number)
{
tab[n++] = number;
}
else
{
break; // break out of loop
}
另请注意,输入失败可能还有其他原因,而不是输入有效数字。
答案 5 :(得分:0)
您的代码存在一些问题:
cin >> number;
您不检查流提取操作是否失败。一种简单的方法是利用operator void*()
转换运算符:
if (cin >> number)
... operation succeeded ...
上述代码相当于检查failbit
和badbit
。
您使用isdigit()
也是错误的,因为您传递了一个数字(例如1234
而不是字符(例如'z'
)。无论如何,添加流提取操作故障检查不需要进行这种基于数字的检查。
答案 6 :(得分:0)
你可以使用来自boost的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;
}
答案 7 :(得分: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.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;
您可以使用其他方法,但是,这些方法可以为您提供一些想法。