使用动态数组求和和和求平均值

Sum and Average with Dynamic Array

本文关键字:平均值 求和 数组 动态      更新时间:2023-10-16

在此之前,我会注意到我对C++和编程都很陌生,所以如果我做了一些不恰当的事情或以奇怪的方式编写代码,那是因为到目前为止我只学到了这么多。

无论如何,我被指派编写一个程序,这是第一个

  • 从用户选择的文件中读取整数
    • 输出所有大于或等于零的数字的总和和平均值
    • 输出所有小于零的数字的总和和平均值
    • 输出所有数字的总和和平均值,无论是正数、负数还是零
    • 然后最后询问用户是否要选择另一个文件再次运行

唯一的问题是我必须在代码中使用一个动态数组,我假设这是为了允许文件容纳任意数量的整数。

到目前为止,除了动态数组的实现之外,我什么都有了。该代码目前被编程为只接受10个整数(因为代码中还没有数组)。

这是我的代码:

#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
int main() {
//Variables
string inFile;
int numbers, i = 0;
double avg, neg_avg, total_sum, total_avg, sum = 0, neg_sum = 0;;
double count = 0, neg_count = 0, pos_count = 0;
char answer;

do
{
//Input Question
cout << "Enter the file name.n";
cin >> inFile;  // Input from User
ifstream fin;   // Open File
fin.open(inFile);
if (fin.fail())  // Check to see if file opens properly
{
cout << "An error occurred while attempting to open the file.n";
exit(1);
}
while (count < 10)
{
fin >> numbers;
if (numbers >= i)
{
sum += numbers;
count += 1;
pos_count += 1;
}
if (numbers < i)
{
neg_sum = neg_sum + numbers;
count = count + 1;
neg_count = neg_count + 1;
}
}

//Calculations
avg = sum / pos_count;
neg_avg = neg_sum / neg_count;
total_sum = sum + neg_sum;
total_avg = total_sum / 10.0;

//OUTPUT
cout << "The sum of all positive numbers is: " << sum << endl;
cout << "The average of all positive numbers is: " << setprecision(3) << avg << endl;
cout << "The sum of all negative numbers is: " << neg_sum << endl;
cout << "The average of all negative numbers is: " << setprecision(3) << neg_avg << endl;
cout << "The sum of all numbers is: " << total_sum << endl;
cout << "The average of all numbers is: " << setprecision(3) << total_avg << endl;
cout << "-------------------------------------------------" << endl;
cout << "Want us to read another file?n";
cout << "Enter 'Y' or 'y'  for yes, any other character for no." << endl;
cin >> answer;
} while ((answer == 'y') || (answer == 'Y'));
return 0;

}

如有任何帮助,我们将不胜感激!提前感谢

更新:

我已经走到了这一步,但当我编译时,程序会连续运行。不确定我做错了什么。

#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
int main() {
//Variables
string file;
int i = 0;
double avg, neg_avg, total_sum, total_avg, sum = 0, neg_sum = 0;;
double neg_count = 0, pos_count = 0, totcount = 0;
char answer;
//Input Question
do
{
cout << "Enter the file name.n";
cin >> file;  // Input from User
ifstream fin;   // Open File
fin.open(file);
if (fin.fail())  // Check to see if file opens properly
{
cout << "An error occurred while attempting to open the file.n";
exit(1);
}
while (!fin.eof())
{
int numbers;
fin >> numbers;
int *dynamicArray;
dynamicArray = new int[numbers];
if (numbers >= i)
{
sum += numbers;
pos_count += 1;
totcount += 1;
}
if (numbers < i)
{
neg_sum = neg_sum + numbers;
neg_count = neg_count + 1;
totcount += 1;
}
//Calculations
avg = sum / pos_count;
neg_avg = neg_sum / neg_count;
total_sum = sum + neg_sum;
total_avg = total_sum / totcount;

//OUTPUT
cout << "The sum of all positive numbers is: " << sum << endl;
cout << "The average of all positive numbers is: " << setprecision(3) << avg << endl;
cout << "The sum of all negative numbers is: " << neg_sum << endl;
cout << "The average of all negative numbers is: " << setprecision(3) << neg_avg << endl;
cout << "The sum of all numbers is: " << total_sum << endl;
cout << "The average of all numbers is: " << setprecision(3) << total_avg << endl;
cout << "-------------------------------------------------" << endl;
delete [] dynamicArray;
}
fin.close();
cout << "Want us to read another file?n";
cout << "Enter 'Y' or 'y'  for yes, any other character for no." << endl;
cin >> answer;
} while ((answer == 'y') || (answer == 'Y'));
return 0;

}

更新:

#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
using namespace std;
int main() {
//Variables
string file;
int i = 0, value = 0, e = 0;
double avg, neg_avg, total_sum, total_avg, sum = 0, neg_sum = 0;;
double neg_count = 0, pos_count = 0, totcount = 0;
char answer;
//Input Question
do
{
cout << "Enter the file name.n";
cin >> file;  // Input from User
ifstream fin;   // Open File
fin.open(file);
if (fin.fail())  // Check to see if file opens properly
{
cout << "An error occurred while attempting to open the file.n";
exit(1);
}

//                       <----------  This works to get the size of the file
int elements;
vector<int> eCount;
while (fin >> elements)
{
eCount.push_back(elements);
}
int size = static_cast<int> (eCount.size());
cout << "size = " << size << endl;//  <-----------Test to see if working 
//From this point, size of the file is held in the variable, 'size'.
int array_size = size;
int* p;
p = new int[array_size];


int location = 0;
while (!fin.eof())
{
fin >> p[location];
location++;
}
cout << "P[12] is equal to " << p[12] << endl;// <----Test to see if array is initialized
while (fin >> p[location])
{

if (p[e] >= i)
{
sum = sum + p[location];
pos_count = pos_count + 1;
totcount = totcount + 1;
}
else 
{
neg_sum = neg_sum + p[location];
neg_count = neg_count + 1;
totcount = totcount + 1;
}
location++;
}
//Calculations
avg = sum / pos_count;
neg_avg = neg_sum / neg_count;
total_sum = sum + neg_sum;
total_avg = total_sum / totcount;
fin.close();
//OUTPUT
cout << "The sum of all positive numbers is: " << sum << endl;
cout << "The average of all positive numbers is: " << setprecision(3) << avg << endl;
cout << "The sum of all negative numbers is: " << neg_sum << endl;
cout << "The average of all negative numbers is: " << setprecision(3) << neg_avg << endl;
cout << "The sum of all numbers is: " << total_sum << endl;
cout << "The average of all numbers is: " << setprecision(3) << total_avg << endl;
cout << "-------------------------------------------------" << endl;



cout << "Want us to read another file?n";
cout << "Enter 'Y' or 'y'  for yes, any other character for no." << endl;
cin >> answer;
} while ((answer == 'y') || (answer == 'Y'));
return 0;
}

感谢所有参与的人。我希望我不必使用动态数组,但不幸的是,如果我不实现一个,我就不会收到。我更新了代码,但似乎无法使数组正常工作,因为它似乎无法正确加载文件中的输入。任何帮助!

好吧,最大的I/O问题是尝试使用while (!fin.eof())进行读取。看看为什么!。循环条件中的eof()总是错误的。。您遇到的最大逻辑问题是在从文件中读取整数的同一循环中包含//Calculations

由于您读取和integer并保持正值和负值的运行和,因此根本不需要动态数组。您当前保留的是pos_count, neg_count, and totcount,这是您在离开读取循环时计算相应平均值所需的全部内容。

为了稍微整理一下,让我们看看您的变量。虽然pos_count, neg_count, and totcount可以使用double,但计数器最好使用unsigned类型。C++提供size_t作为计数和长度的首选sizetype,但它不是强制性的,只是有意义。虽然您可以使用单独的fileanswer,但最好将每个输入读取到std::string中,以确保单次击键(就像用户键入"Yes"而不是'Y')不会在stdin中留下未读的其他字符。您也可以对fileanswer使用相同的std::string,只需检查第一个字符是'y'还是'Y'即可控制读取另一个文件循环。

综合起来,你的变量可能很简单:

int main (void) {
std::string buffer;     /* use single buffer for filename & answer */
do
{   // Variables   (will be reinitialized for each file)
int number;             /* you are reading one number at a time */
size_t  neg_count = 0, pos_count = 0, totcount = 0;
double  avg, neg_avg, total_sum, total_avg, sum = 0., neg_sum = 0.;

(注意:用于读取答案的缓冲区是必须在do {...} while();循环之前声明的唯一变量,以便在结束时用作测试条件)

如果您什么都不记得,记得验证每个输入,例如

std::cout << "Enter the file name: ";
if (!(std::cin >> buffer)) {            // VALIDATE Input from User
std::cerr << "(user canceled input)n";
return 1;
}

虽然您可以检查流上是否设置了.fail()位,但更通用的测试是文件流goodbit是否未设置,例如

std::ifstream fin(buffer);              // open file stream
if (!fin.good()) {      // Check to see if file opens properly
std::cerr << "error: file open failed - " << buffer << ".n";
return 1;
}

(注意:任何一种方式都可以)

当你在循环中阅读时,以成功阅读为条件。你在这里的阅读循环只需要:

while (fin >> number) { /* control read loop with read itself */
if (number >= 0) {  /* handle positive numbers */
sum += number;
pos_count += 1;
}
else {              /* if it's not >= 0, it's negative */
neg_sum = neg_sum + number;
neg_count = neg_count + 1;
}
totcount += 1;      /* total count incremented each time */
}
fin.close();

这将从您的文件中捕获您需要的所有信息。现在进行平均计算,但如果pos_count, neg_count, or totcount == 0会发生什么。除以通常是一件非常非常糟糕的事情。始终验证分母,例如

// Calculations
if (pos_count > 0)
avg = sum / pos_count;
else
avg = 0;
if (neg_count > 0)
neg_avg = neg_sum / neg_count;
else
neg_avg = 0;
total_sum = sum + neg_sum;
if (totcount > 0)
total_avg = total_sum / totcount;
else
total_avg = 0;

现在是您的输出。对于一个连续的输出块,您想调用cout多少次?(提示:一次)

//OUTPUT    (you only need one std::cout)
std::cout << "nThe sum of all positive numbers is: " 
<< sum << std::endl
<< "The average of all positive numbers is: " 
<< std::setprecision(3) << avg << std::endl 
<< "The sum of all negative numbers is: " 
<< neg_sum << std::endl 
<< "The average of all negative numbers is: " 
<< std::setprecision(3) << neg_avg << std::endl 
<< "The sum of all numbers is: " << total_sum << std::endl 
<< "The average of all numbers is: " << std::setprecision(3) 
<< total_avg << std::endl 
<< "-------------------------------------------------nn" 
<< "Want to read another file?n" 
<< "Enter 'Y' or 'y'  for yes, any other character for no.n";

它在一个调用中处理所有输出需求(包括'Y''y'的提示)。现在只需使用相同的std::string来输入是否继续,例如

if (!(std::cin >> buffer)) {
std::cerr << "(user canceled input)n";
return 1;
}
/* condition on 1st char in buffer */
} while ((buffer.at(0) == 'y') || (buffer.at(0) == 'Y'));
}

就这样,你完了。把它放在一起,用getline (std::cin, buffer)代替std::cin >> buffer的脆弱使用:

#include <iostream>
#include <fstream>
#include <iomanip>
int main (void) {
std::string buffer;     /* use single buffer for filename & answer */
do
{   // Variables   (will be reinitialized for each file)
int number;             /* you are reading one number at a time */
size_t  neg_count = 0, pos_count = 0, totcount = 0;
double  avg, neg_avg, total_sum, total_avg, sum = 0., neg_sum = 0.;
std::cout << "Enter the file name: ";
if (!getline(std::cin, buffer)) {       // VALIDATE Input from User
std::cerr << "(user canceled input)n";
return 1;
}
std::ifstream fin(buffer);              // open file stream
if (!fin.good()) {      // Check to see if file opens properly
std::cerr << "error: file open failed - " << buffer << ".n";
return 1;
}
while (fin >> number) { /* control read loop with read itself */
if (number >= 0) {  /* handle positive numbers */
sum += number;
pos_count += 1;
}
else {              /* if it's not >= 0, it's negative */
neg_sum = neg_sum + number;
neg_count = neg_count + 1;
}
totcount += 1;      /* total count incremented each time */
}
fin.close();
// Calculations
if (pos_count > 0)
avg = sum / pos_count;
else
avg = 0;
if (neg_count > 0)
neg_avg = neg_sum / neg_count;
else
neg_avg = 0;
total_sum = sum + neg_sum;
if (totcount > 0)
total_avg = total_sum / totcount;
else
total_avg = 0;
//OUTPUT    (you only need one std::cout)
std::cout << "nThe sum of all positive numbers is: " 
<< sum << std::endl
<< "The average of all positive numbers is: " 
<< std::setprecision(3) << avg << std::endl 
<< "The sum of all negative numbers is: " 
<< neg_sum << std::endl 
<< "The average of all negative numbers is: " 
<< std::setprecision(3) << neg_avg << std::endl 
<< "The sum of all numbers is: " << total_sum << std::endl 
<< "The average of all numbers is: " << std::setprecision(3) 
<< total_avg << std::endl 
<< "-------------------------------------------------nn" 
<< "Want to read another file?n" 
<< "Enter 'Y' or 'y'  for yes, any other character for no.n";
if (!getline(std::cin, buffer)) {
std::cerr << "(user canceled input)n";
return 1;
}
/* condition on 1st char in buffer */
} while ((buffer.at(0) == 'y') || (buffer.at(0) == 'Y'));
}

(注意:getline (std::cin, buffer)已在上面的代码中使用,以使用户输入更加健壮——原因请参阅下面的示例输出部分)

示例使用/输出

使用三个文件进行测试,第一个文件是一组50x5的正整数,然后是一组10个具有一个负值的整数(-2213),最后一个文件是100个正负混合值的文件,将给出:

$ ./bin/pos_neg_total
Enter the file name: dat/50x5.txt
The sum of all positive numbers is: 122180
The average of all positive numbers is: 489
The sum of all negative numbers is: 0
The average of all negative numbers is: 0
The sum of all numbers is: 1.22e+05
The average of all numbers is: 489
-------------------------------------------------
Want to read another file?
Enter 'Y' or 'y'  for yes, any other character for no.
y
Enter the file name: ../../..//src-c/tmp/dat/10int_nl.txt
The sum of all positive numbers is: 2.03e+05
The average of all positive numbers is: 786
The sum of all negative numbers is: -2.21e+03
The average of all negative numbers is: -2.21e+03
The sum of all numbers is: 2.01e+05
The average of all numbers is: 774
-------------------------------------------------
Want to read another file?
Enter 'Y' or 'y'  for yes, any other character for no.
Y
Enter the file name: ../../../src-c/tmp/dat/100int.txt
The sum of all positive numbers is: 1.93e+06
The average of all positive numbers is: 5.55e+03
The sum of all negative numbers is: -2.29e+05
The average of all negative numbers is: -1.76e+04
The sum of all numbers is: 1.7e+06
The average of all numbers is: 4.71e+03
-------------------------------------------------
Want to read another file?
Enter 'Y' or 'y'  for yes, any other character for no.
n

有很多种方法可以将其组合在一起,您可以随意使用任意多的变量或对std::cout的调用,但希望这将帮助您进一步思考"我的程序需要什么?"。

使用>>进行用户输入是脆弱的

最后,要知道,使用std::cin >> string进行用户输入是非常脆弱的,因为用户作为输入的一部分键入的任何空白都不会被读取(并且它将在stdin中留下未读。使用getline会将整行读取到字符串中要好得多。不要在不考虑stdin中可能留下的任何'n'的情况下将>>iostream用于输入与getline混合使用。然后可以使用std::cin.ignore()进行清除。在您的情况下,使用getline接受所有用户输入会更健壮,例如.

if (!getline(std::cin, buffer)) {          // VALIDATE Input from User
std::cerr << "(user canceled input)n";
return 1;
}

然后,带有whtespace的文件名将得到正确处理,如果用户想键入"Yes I want to enter another file!"作为对您的继续问题的回答,那么这将不会带来任何问题。如果你的课上还没有达到,就把它放在你的臀部口袋里。对于一个实验,请尝试将两个用户输入都替换为上面显示的原始std::cin >> buffer,并查看如果在提示:)处键入"Yes I want to enter another file!"会发生什么

如果您还有其他问题,请告诉我。

所以为什么需要一个向量(动态数组)来存储整数,因为您的代码可以通过在EOF的条件下添加一个"break"表达式来处理所有情况。如果你真的需要它,下面是你需要的:

#include<vector>
vector<int> my_vec;