动态数组的求和和平均值 [英] Sum and Average with Dynamic Array

查看:98
本文介绍了动态数组的求和和平均值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我会指出我对C ++和程序设计非常陌生,因此,如果我做的事情不正确或以奇怪的方式编写代码,那是因为到目前为止我只学到了很多东西。

I'll preface this by noting that I'm very new to C++ and programming in general so if I'm doing something improperly or writing code in an odd way, it's because i've only learned so much so far.

无论如何,我被分配编写一个程序,首先

Anyways, I was given an assignment to write a program that first


  • 从用户选择的文件中读取整数


    • 输出所有大于或等于零的数字的和与平均值,

    • 输出所有小于零的数字的和与平均值

    • 输出所有小于零的数字的和与平均值。

    • 然后最后询问用户是否要选择另一个文件再次运行

    • Reads integers from a file of the user's choice
      • Outputs the sum and average of all the numbers greater than or equal to zero ,
      • Outputs the sum and average of all the numbers less than zero
      • Outputs the sum and average of all the numbers, whether positive, negative, or zero.
      • Then finally asks the user if they'd like to choose another file to run on again

      唯一要注意的是,我假设必须在代码内使用动态数组,以允许文件容纳任意数量的整数。

      The only catch is that I have to use a dynamic array within the code, I'm assuming in order to allow the file to hold any amount of integers.

      到目前为止,除了执行动态数组。该代码当前被编程为仅接受10个整数(因为代码中还没有数组)。

      So far, I have everything except for the implementation of the dynamic array. The code is currently programmed to only accept 10 integers (as there are no arrays in the code yet).

      这是我的代码:

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

      任何帮助将不胜感激!
      预先感谢

      Any help would be greatly appreciated! Thanks in advance

      更新:

      我已经走了这么远,但是当我编译时,该程序连续运行。不确定我在做什么错。

      I've gotten this far but when I compile, the program runs continuously.Not sure what I'm doing wrong.

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

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

      Thank you to everyone who's pitched in. I wish I didn't have to use a dynamic array but unfortunately I won't receive if I don't implement one. I updated my code but I can't seem to get the array working properly as it does not seem to load the input from the file properly. Anything helps!

      推荐答案

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

      Well, the biggest I/O problem you have is attempting to read with while (!fin.eof()). See Why !.eof() inside a loop condition is always wrong.. The biggest logic problem you are having is including the //Calculations in the same loop you are reading your integers from your file.

      由于您读取并整数并且保持正值和负值的连续和,因此根本不需要动态数组。当前,您保留 pos_count,neg_count和totcount ,这是在离开读取循环时计算各自平均值所需的全部条件。

      Since you read and integer and are keeping a running sum of the positive and negative values, there is no need for a dynamic array at all. You are currently keeping pos_count, neg_count, and totcount which are all you need to compute the respective averages when you leave your read loop.

      要整理一点,让我们看一下您的变量。虽然您可以对 pos_count,neg_count和totcount 使用 double ,但最好使用 unsigned 类型的计数器。 C ++提供了 size_t 作为首选的 sizetype ,用于计数和长度,但这不是强制性的-很有道理。虽然可以使用单独的文件 answer ,但最好将每个输入读入 std :: string 以确保一次击键(例如用户键入而不是'Y')不会在 stdin 中保留未读的其他字符。您还可以对文件 answer 使用相同的 std :: string code>,只需检查第一个字符是'y'还是'Y'来控制您的读取另一个文件循环。

      To tidy things up a bit, let's look at your variables. While you can use double for pos_count, neg_count, and totcount, it's better to use an unsigned type for a counter. C++ provides size_t as a preferred sizetype for counts and lengths, but it's not mandatory -- it just makes sense. While you can use a separate file and answer, it is better to read each input into a std::string to ensure a single keystroke (like the user typing "Yes" instead of 'Y') doesn't leave additional characters unread in stdin. You can also use the same std::string for both your file and answer and just check the if the first character is 'y' or 'Y' to control your read another file loop.

      放在一起,您的变量可能很简单:

      Putting that together, your variables could simple be:

      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(); 循环之前声明,以用作最后的测试条件)

      (note: buffer to read the answer into is the only variable that must be declared before your do {...} while(); loop to be used as the test condition at the end)

      如果您什么都没记住,请记住验证每个输入,例如

      If you remember nothing else, remember to validate every input, e.g.

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

      虽然您可以检查 .fail() 位设置为流,更一般的测试是是否未设置文件流 goodbit ,例如

      While you can check if the .fail() bit is set on the stream, a more general test is if the file stream goodbit is not set, e.g.

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

      注意:任一种方法都可以)

      在循环中读取时,请以成功读取为条件来调节循环。这里的读取循环只不过是:

      When you read in a loop, condition your loop on a successful read. Your read loop here needs to be nothing more than:

              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或totcount == 0 会发生什么。除以通常是一件非常非常糟糕的事情。始终验证您的分母,例如

      That will capture all the information you need from your file. Now do the average calculations, but what happens if pos_count, neg_count, or totcount == 0. Dividing by zero is generally a really, really bad thing. Always validate your denominator, e.g.

              // 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 多少次? (提示:一次)

      Now for your output. How many times do you want to call cout for one continual block of output? (hint: once)

              //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 
                      << "-------------------------------------------------\n\n" 
                      << "Want to read another file?\n" 
                      << "Enter 'Y' or 'y'  for yes, any other character for no.\n";
      

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

      That handles all your output needs in a single call (including your prompt for 'Y' or 'y'). Now just use the same std::string to take input on whether to continue or not, e.g.

              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'));
      }
      

      就是这样。放在一起,并替换 std :: cin>>的易用用法。缓冲区 getline(std :: cin,缓冲区),您将拥有:

      That's it you are done. Putting it altogether, and replacing the fragile use of std::cin >> buffer with getline (std::cin, buffer) you would have:

      #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 
                      << "-------------------------------------------------\n\n" 
                      << "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),使用户输入更加健壮-出于示例原因,请参见示例输出下面的部分)

      (note: getline (std::cin, buffer) has been used in the code above to make the user input a bit more robust -- see the the section below the example output for the reasons)

      示例用法/输出

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

      Testing with three files, the first a 50x5 set of positive integers, then next a set of 10 integers with one negative value (-2213) and the last a file of 100 mixed positive and negative values would give:

      $ ./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 的调用,但希望这将有助于您进一步思考我的程序需要什么?。

      There are many, many ways to put this together, and you are free to use as many variables or calls to std::cout as you like, but hopefully this will help you think further along the lines of "What does my program require?".

      使用>> 进行用户输入很容易

      Using >> for User-Input is Fragile

      最后,请注意,使用 std :: cin>>用户输入的字符串非常脆弱,因为用户键入作为输入一部分的任何空格都不会被读取(并且在未读 > stdin 。最好使用 getline 它将完整的行读入您的字符串中。不要混用> iostream进行输入,其中 getline 表示任何'\ 'n'可能留在 stdin 中,然后可以使用 std :: cin.ignore()要清除。在您的情况下,使用 getline 来接受所有用户输入将更加可靠,例如

      As a final note, know that using std::cin >> string for user-input is horribly fragile as any whitespace the user types as part of the input will not be read (and it will be left unread in stdin. It is far better to use getline which will read the complete line into your string. Don't mix using the >> iostream for input with getline without accounting for any '\n' that may be left in stdin. You can then use std::cin.ignore() to clear. In your case it would simply be more robust to take all user input with getline, e.g.

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

      然后用如果用户想要键入是,我想输入另一个文件! 作为他对您继续问题的回答,那根本不会有问题。如果您还没有上课,请把它放在臀部口袋中。为了进行实验,请尝试使用原始的 std :: cin>>替换上面显示的两个用户输入。缓冲,看看如果在提示符上键入是,我想输入另一个文件! ,会发生什么情况/ code>

      Then filenames with whtespace would be properly handled, and if the user wanted to type "Yes I want to enter another file!" as his answer to your continue question, that would pose no problem at all. If you haven't got there yet in your class, put it in your hip-pocket. For an experiment, try replacing both user inputs with what is shown above with your original std::cin >> buffer and see what happens if you type "Yes I want to enter another file!" at the prompt :)

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

      Let me know if you have further questions.

      这篇关于动态数组的求和和平均值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆