0

I am new to the stackoverflow communiy and new to coding so apologies in advance whie I learn the ropes of posting here as well as the rules of coding. I am using C++ and am in a CS161 beginner Computer Science class.

I am currently working on an assignment which asks me to read from a data file stored on my computer and sort the data in order to do some calculations, which, in this assignment is finding the average test scores based on sex and type of school. everything compiles and the program runs but there are a few problems.

The first problem is with my echo.

    // echo the data file
    while (inData)
    {
    inData >> name >> sex >> school >> score;
    cout << name << sex << school << score << endl;

The program does echo the data but it ends up echoing the last name on the list, twice for some reason. Also, (and I don't know if this matters) when it does echo, it does not skip spaces inbetween name, sex, school, and score.

The second problem is that it isn't executing the calculations and I think it is because I am missing a "count" related instruction of some sort but I am stumped as far as what I can do.

Here is my code, let me know what you think:

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
int main()
{
    //Declare variables to manipulate data
    char sex;
    string name;
    string school;
    string fileSource;
    string CC;
    string UN;
    int maleScore = 0;
    int femScore = 0;
    int unScore = 0;
    int ccScore = 0;
    double maleAvg;
    double femAvg;
    double unAvg;
    double ccAvg;
    double sumAvg = 0;
    int femCount = 0;
    int maleCount = 0;
    int ccCount = 0;
    int unCount = 0;
    int score;
    int sum;
    //Declare stream variables
    ifstream inData;
    ofstream outData;
    inData >> name >> sex >> school >> score;
    // Promt user for file location
    cout << "Please input file location: ";
    cin >> fileSource;

    // open output file and run program exit failsafe command
    inData.open(fileSource);
    if (!inData)
    {
        cout << "Cannot open input file. "
            << "Program will now terminate." << endl;
        return 1;
    }
    outData << fixed << showpoint << setprecision(2);

    // echo the data file
    while (inData)
    {
        inData >> name >> sex >> school >> score;
        cout << name << sex << school << score << endl;

        // while reading incoming data from file, execute the conditions

        // Male and female calculations
        if(sex=='M')
        {
            maleScore = maleScore +=score;
            ++maleCount;
        }
        else if(sex =='F')
        {
            femScore = femScore +=score;
            ++femCount;
        }

        // Community college and University calculations
        if(school == CC)
        {
            ccScore = ccScore +=score;
            ++ccCount;
        }
        else if(school == UN)
        {
            unScore = unScore +=score;
            ++unCount;
        }
        maleAvg = maleScore/maleCount;
    }

    // Male average output
    cout << maleAvg;

    femAvg = femScore/femCount;

    // Female average output
    cout << femAvg;

    ccAvg = ccScore/ccCount;

    // Community College average output
    cout << ccAvg;

    unAvg = unScore/unCount;

    // University average output
    cout << unAvg;
    sum = maleScore + femScore + ccScore + unScore;
    sumAvg = sum/12;
    cout << sumAvg;
    return 0;
}

Also, my compiler keeps running the program and does not stop. I took a pic of my compiler window but don't know how to post it.

Caesar
  • 8,395
  • 6
  • 34
  • 62
Jason
  • 59
  • 10
  • 1
    Can you show us a sample of the input file that is supposed to be used? – Nik Bougalis Feb 13 '13 at 21:48
  • Here is an example: Bailey M CC 68. The column one is the string name Bailey,column two char M is gender, column three string CC is school (the other option was UN for university) , and last column score is the integer 68. There is a list of these in the file. – Jason Feb 13 '13 at 21:57
  • Also, I changed the while (inData) to while (! inData.eof()). Is that better? – Jason Feb 13 '13 at 21:59
  • 1
    I think `while(inData >> name >> sex >> school >> score)` would be better. – andre Feb 13 '13 at 22:11
  • Thank you for that. Still, even after making that change, I still have all of those problems though. Nothing changed. It still isn't doing any of the calculations and it is still perpetually running until I manually stop it. Mainly though, I am concerned with how to get my calculations to run. Any thoughts? It looks solid, I can't figure out why it isn't calculating. – Jason Feb 13 '13 at 22:17
  • You have a few issues - please look at my answer for a detailed explanation. – Nik Bougalis Feb 13 '13 at 22:21

1 Answers1

1

You have a few issues with your code. Let's take things one at a time, shall we?

ifstream inData;
ofstream outData;
inData >> name >> sex >> school >> score;

What does the last line do? inData isn't open and yet you're trying to read from it.

maleScore = maleScore +=score;

Here (and in a few other places) you are using the += operator incorrectly. You should either use += like this:

maleScore += score;

or use + like this:

maleScore = maleScore + score;

You then do this:

if(school == CC)

Now, CC is an std::string in your code, which you have not initialized (which means that it is empty). So it will never match, therefore the if body will never execute. The same thing happens with UN.

Further down, you have this line inside the loop:

maleAvg = maleScore/maleCount;

What this does is recalculate the average for males every time through the loop. That's not necessarily wrong (you will get the right result) but if the first person in the file is a female, your program will crash with a division by zero, since maleCount will be 0. The same thing will happen if no females are in the input file, or if there are no scores from a University or a College.

Lastly, using iostream::eof() inside a loop is not a good idea. You can read more about that right here on StackOverflow: Why is iostream::eof inside a loop condition considered wrong?

With all that said, your mistakes aren't really serious and are typical of new programmers, so don't get discouraged. Think of this as an opportunity to learn and to understand how to examine your code to find these sort of bugs. So without further ado, let's see an improved version of this program:

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>

using namespace std; // it's considered bad to do this - but since
                     // this is homework, we'll let it slide.

int main()
{
    //Declare variables to manipulate data    
    string name;
    string fileSource;

    int maleScore = 0;
    int femScore = 0;
    int unScore = 0;
    int ccScore = 0;
    int femCount = 0;
    int maleCount = 0;
    int ccCount = 0;
    int unCount = 0;

    //Declare stream variables
    ifstream inData;
    ofstream outData;

    // Promt user for file location
    cout << "Please input file location: ";
    cin >> fileSource;

    // open output file and run program exit failsafe command
    inData.open(fileSource);

    if(!inData)
    {
        cout << "Cannot open input file. "
             << "Program will now terminate." << endl;
        return 1;
    }    

    cout << "Reading data from '" << fileSource << "'" << endl;

    while(inData >> name)
    { // If we read a name, we can continue. Otherwise, we're done.     
        char sex;       
        int score;
        string school;

        inData >> sex >> school >> score;

        // Write the data out
        cout << "Processing " << name << " (" << sex << ") attending ";

        if(school == "UN")
            cout << "University";
        else if(school == "CC")
            cout << "Community College";

        cout << ". Score = " << score << endl;

        // Male and female calculations
        if(sex=='M')
        {
            maleScore +=score;
            maleCount++;
        }
        else if(sex =='F')
        {
            femScore +=score;
            femCount++;
        }

        // Community college and University calculations
        if(school == "CC")
        {
            ccScore +=score;
            ccCount++;
        }
        else if(school == "UN")
        {
            unScore +=score;
            unCount++;
        }       
    }

    // We do static_cast<double>(maleScore) / maleCount; to ensure that
    // the division is done using floating point and not integer 
    // arithmetic. We could have multiplied the numerator by 1.0 instead.

    if(maleCount != 0)
    {
        cout << "The average scores for males is: " << setprecision(2)
             << static_cast<double>(maleScore) / maleCount << endl;
    }

    if(femCount != 0)
    {
        cout << "The average score for females is: " << setprecision(2)
             << static_cast<double>(femScore) / femCount << endl;
    }

    if(ccCount != 0)
    {
        cout << "The average score for Community Colleges is: " << setprecision(2)
             << static_cast<double>(ccScore) / ccCount << endl;
    }

    if(unCount != 0)
    {
        cout << unScore << "/" << unCount << endl;

        cout << "The average score for Universities is: "  << setprecision(2)
             << static_cast<double>(unScore) / unCount << endl;
    }

    // In this case we will use the multiplication technique instead:   
    cout << "The 'sum' average is: " << setprecision(2)
         << (1.0 * (maleScore + femScore + ccScore + unScore)) / 12 << endl;

    return 0;
}
Community
  • 1
  • 1
Nik Bougalis
  • 10,222
  • 1
  • 19
  • 37
  • Wow! You addressed all of my concerns in one crushing logical blow haha. I tried my best to see what I can consolidate there but I am in a basic class so we only now just started talking about arrays. The only thing I was able to improve with the setprecision. I placed this line before calculating any averages: cout << fixed << showpoint << setprecision(2) << endl; – Jason Feb 14 '13 at 08:36
  • As I said, this wasn't a bad effort - you are new at programming and it will take some time and practice before you "get in the zone". Don't get discouraged - just keep plugging away. We were *all* new programmers at one time. Good luck! – Nik Bougalis Feb 14 '13 at 09:01