-3

I have this batting average program. My problem is that I cannot output this program using input/output files so that it shows the highest/lowest averages and the names to go with them. The code I have in main is not right because it is only outputting "Highest batting average is: 0" and "Players with the highest batting average: " None of the averages are 0 so it should not be outputting that, and there should be a name next to the highest batting average. The same goes with the lowest. This is what I have so far:

#include "Player.h"
#include "Stack.h"
#include <fstream>

using namespace std;

int main()
{
    Player x;
    string name;
    double avg;
ifstream infile("avgs.txt"); 
    while (infile >> name >> avg)
    {
        x.insertPlayer(name, avg);
    }

    infile.close();
    x.printHigh();
    x.printLow();

    if(!infile)
    {
        cout << "Unable to open the file for writing " << endl;
        exit(0);
    }

    ofstream outfile("avgs.txt");
    if (!outfile)
    {
        cout << "Error opening file " << endl;
        exit(0);
    }
    outfile << endl;
}

Here are the files to the Player class, and the Stack class in case it is needed aswell:

////Player.h
#include "stdafx.h"
#include <iostream>
#include <string>
#include "Stack.h"

using std::string;

class Player
{
public:
    double lowest;
    double highest;
    Stack<string> low;
    Stack <string> high;
    void insertPlayer(string name, double batAvg);
    void printHigh();
    void printLow();
};

This is the .cpp file for the Player class:

#include "stdafx.h"
#include <iostream>
#include <string>
#include "Player.h"

using namespace std;
using std::string;

void Player::insertPlayer(string name, double batAvg)
{
    cout << "Player " << name << " has an average of: " << batAvg << endl;
    if (low.empty() && high.empty())
    {
        low.push(name);
        high.push(name);
        highest = lowest = batAvg;
    }
    else
    {
        if (batAvg>highest)
        {
            while (!high.empty())
                high.pop();
            highest = batAvg;
            high.push(name);
        }
        else if (batAvg == highest)
                high.push(name);
            else if (batAvg<lowest)
                {
                    while (!low.empty())
                        low.pop();
                    lowest = batAvg;
                    low.push(name);
                }
                else if (batAvg == lowest)
                        low.push(name);
    }
}

void Player::printHigh()
{
    cout << "Highest batting average is: " << highest << endl;
    cout << "Players with the highest batting average: " << endl;
}

void Player::printLow()
{
    cout << "Lowest batting average is: " << lowest << endl;
    cout << "Players with the lowest batting average: " << endl;
}

And my Stack class if it is needed:

#ifndef STACK
#define STACK

#include "stdafx.h"
#include <iostream>
#include <vector>

using namespace std;

template <class T>
class Stack : public exception
{
private:
    vector<T>myStacks;
public:
    void push(T const& uStack);
    void pop();
    T peek() const;
    bool empty() const
    {
        return myStacks.empty();
    }
};

template <class T>
void Stack<T>::push(T const& uStack)
{
    myStacks.push_back(uStack);
}

template <class T>
void Stack<T>::pop()
{
    if (myStacks.empty())
    {
        throw std::out_of_range("Stack <>::pop(): This is an empty stack ");
    }
    myStacks.pop_back();
}

template <class T>
T Stack<T>::peek() const
{
    if (myStacks.empty())
    {
        throw std::out_of_range("Stack<>::peek(): This is an empty stack ");
    }
    return myStacks.back();
}

#endif

The focus code that I am trying to output is Player.cpp, but the Stack.h and Player.h are needed to make it run. In main() I need to output the names, averages, and the people with the highest/lowest averages. Any help is appreciated!

The text file consists of players and their averages, for example: Orlando .775 Charles .606 J.D. .775 Gina .400 Sam .702 Rich .686

and so on.

Mgonz
  • 1
  • 3
  • 1
    Please double check whether all of that code is really part of a [mcve]. I would like to put some stress on the "Minimal". Also you need to provide more information on how exactly you know that you did not get it right. What is wrong? What undesired happens? What desired does not happen? Provide sample input and desired output. Describe problems: Compiler error? Warning? Crash? Hang? Misbehaviour? – Yunnosch May 21 '18 at 08:48
  • Generally, if you do these thoroughly and they don't help you on, then I will pay a nice dinner, if we ever meet. https://ericlippert.com/2014/03/05/how-to-debug-small-programs/ https://ericlippert.com/2014/03/21/find-a-simpler-problem/ https://stackoverflow.com/questions/2069367/how-to-debug-using-gdb – Yunnosch May 21 '18 at 08:50
  • "I need to output the names" to where? Are you failing to read the input file? Are you failing to write the output file? Note that you are overwriting your input each run. I would try writing a separate file first – Caleth May 21 '18 at 08:51
  • @Caleth The program should output the highest and lowest averages and the names to go along with these averages. I believe I am failing to read the input file properly. – Mgonz May 21 '18 at 08:58
  • "I need to output ..." **to where**? A file? the standard output? – Caleth May 21 '18 at 08:58
  • It is a standard output. – Mgonz May 21 '18 at 09:00
  • 2
    What is the problem? _"I cannot seem to get it right"_ and _"I am struggling"_ and _"I believe I am failing"_ are not problem descriptions. – Lightness Races in Orbit May 21 '18 at 09:12
  • Please take the [tour], especially read [ask]. You need to see your question from the point of view of somebody trying hard to help you. Please write everything down, what you plan, what your assumptios are (though that is admittedly hard), **what is wrong**. I cannot find anything on what is wrong in your question. You never say. You only describe what it should do, but not what it does. Thanks for showing code, but it does not mean you can rely on people running it and then guessing what is wrong. Actually you should not even expect people to run it. Explain, please. Describe, please. – Yunnosch May 21 '18 at 09:17
  • Please try to delete everything from your code which is not needed to reproduce whatever it is that you do not like. The shorter the code, the more likely actual help is. It is called making a [mcve]. Those blue words are a link, please click it, read, apply the concept to your question. – Yunnosch May 21 '18 at 09:19
  • I have this batting average program. My problem is that I cannot output this program using input/output files so that it shows the highest/lowest averages and the names to go with them. The code I have in main is not right because it is only outputting "Highest batting average is: 0" and "Players with the highest batting average: " None of the averages are 0 so it should not be outputting that, and there should be a name next to the highest batting average. The same goes with the lowest. – Mgonz May 21 '18 at 09:20
  • For an MCVE, try to reduce complexity. Putting everything into a single file could be part of that. (Though a structured project is otherwise a good idea.) If you need multiple files, then very likely your code is NOT minimal. – Yunnosch May 21 '18 at 09:21
  • Better, thanks. But please put that helpful additional information into the question itself, instead of hiding it in a comment. Also the question offers much better formatting options. Use them to make even clearer what exactly you are seeing. – Yunnosch May 21 '18 at 09:22
  • Alright I added this description in the question itself. – Mgonz May 21 '18 at 09:25
  • Can you reduce complexity by dropping the input/output files? Output to stdout, do not input at all, use initialised variables. Initialise with hardcoded assignments if necessary. If this removes your problem, then swap around, skip everything with dataprocessing and concentrate on only outputting from initialised variables to output file. If that has no problem, then the input is the problem. Use this concept to narrow down to one smaller part of the whole. It is part of the "find a simpler problem concept" I linked. It really is helpful. Try it. – Yunnosch May 21 '18 at 09:26
  • Please use formatting. You inserted a block of text without even a newline. Try it. Read the help on formatting. If the finer details of the markdown formatting are a mystery, then somebody will help you. But you have to try yourself, for the purpose of making sure that what we see is what you see. Your program does not print without any newlines, does it? – Yunnosch May 21 '18 at 09:28
  • Whenever I dealt with input/output files I had to follow the structure of using both of them. I am not experienced in c++ too much. Could you provide example code to clarify? – Mgonz May 21 '18 at 09:29
  • Asking for a tutorial on input and output is off-topic. If that is the simpler problem you need to master, then do that first. Please. https://ericlippert.com/2014/03/21/find-a-simpler-problem/ – Yunnosch May 21 '18 at 09:30

1 Answers1

0

The first thing you want to do is remove everything after x.printLow(); in main, then verify that the expected input is present in avgs.txt.

Your code will overwrite the input file with a single newline, so if you have tried it once, you probably haven't got the input you expect anymore. Notice how you never see output from cout << "Player " << name << " has an average of: " << batAvg << endl;. That indicates insertPlayer is not being called.

I'm pretty sure it is a problem with finding your input file, as it works with a different input source. Is the file with the text in the same folder as your .exe? Is it instead in a different folder, such as where the source files are?

A simple test would be to just copy the contents of the file to cout, to see what the program finds

int main() {
    std::ifstream infile("avgs.txt");
    for (std::string line; std::getline(infile, line;) {
        std::cout << line << std::endl;
    }
}
Caleth
  • 52,200
  • 2
  • 44
  • 75
  • You're right, insertPlayer is not doing anything and I believe it needs to be called for printHigh and printLow to output their correct values too. I thought it was being called. How would I fix this so that insertPlayer is indeed being called? – Mgonz May 21 '18 at 09:38
  • Go look at "avgs.txt". Is it empty? Should it be empty? – Caleth May 21 '18 at 09:39
  • No, it is not empty and it should not be. avgs.txt is a list of players and their batting averages. – Mgonz May 21 '18 at 09:41
  • Can you add a few lines from it to your question – Caleth May 21 '18 at 09:44
  • Sure I added it in – Mgonz May 21 '18 at 09:47
  • Wait so my input file code is correct? Or did you change something to make it work? – Mgonz May 21 '18 at 09:56
  • I switched the input filestream to an input stringstream, as online compilers don't have accessible files – Caleth May 21 '18 at 09:58
  • Hmmm. Am I suppose to download this link that contains the players and their averages in order for the code to work? – Mgonz May 21 '18 at 10:03
  • No, you should investigate whether the file you think you are reading is in fact the file that is being read. The link shows that the problem is with the file. The rest of the program works in the manner you are asking for – Caleth May 21 '18 at 10:23