Hi, I have a C++ programming assignment and am new to programming. My assignment is to read from an input file into an array of structs but for some reason all im reading in is garbage could really use some advice. If anybody could help thank you.

Heres my code so far:

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

using namespace std;
//Struct for Athletes
struct Athletes
{
    int athletenum;
    char sport[5];
    double score[5];
};
void openfiles(ifstream & ,ofstream & );
void getathletes(ifstream &, Athletes scrlist[100]);
double total(double total, Athletes scrlist[100]);
void printcontestants(Athletes scrlist [100], ofstream &, double, double, int, char );


int main()
{
    //Declares an array of type struct
    Athletes scrlist[100];

    double total1=0, total2=0;
    int winner=0;
    int contestant=0;
    ifstream infile;
    ofstream outfile;
    openfiles(infile, outfile);
    outfile << "Kenley O'Brien" << endl;
    outfile << "CMPS 2 Program 1" << endl;
    if(infile.fail())
        cout << " error opening file " << endl;

    getathletes(infile, scrlist);
    printcontestants(scrlist, outfile, total1, total2, winner, contestant);
    outfile << "Athlete of the Year: " << contestant << "With a total score of: " << winner << endl;
    outfile << " Computer Science Rocks!!!!!!!" << endl;
        infile.close();
        outfile.close();
        system("pause");
        return 0;
    }
//function to open files
void openfiles(ifstream & infile, ofstream & outfile)
{
    char infilename[20];
    char outfilename[20];
    cout << "Please enter a file name for use: " << endl;
    cin >> infilename;
    cout << "Please enter a file for the output: " << endl;
    cin >> outfilename;
    infile.open(infilename);
    outfile.open(outfilename);

}
//funciton to read in from file into array of structs
 void getathletes(ifstream & infile, Athletes scrlist[100])
{
    int i=0;
    infile>>scrlist[i].athletenum;
    while(scrlist[i].athletenum)
    {

            infile >> scrlist[i].athletenum;
            for(int j=0; j<5; j++)
                {

                    infile >> scrlist[i].sport[j];
                    infile >> scrlist[i].score[j];

                }
            i++;
    }

}

//prints out athlete data
//for some reason I could not get this function to work
void printcontestants(Athletes scrlist[100], ofstream & outfile, double total1, double total2, int winner, char contestant)
{
    for(int i=0; i<100; i++)
    {
        outfile << scrlist[i].athletenum;
        for(int j=0; j<5; j++)
        {
        if(scrlist[i].sport[j]=='D')
                outfile << "Diving; ";
            else if(scrlist[i].sport[j] == 'G')
                outfile << "Gymnastics: ";
            else if(scrlist[i].sport[j] == 'B')
                outfile <<"Boxing: ";
            else if(scrlist[i].sport[j] == 'S')
                outfile <<"Skating: ";
            else if(scrlist[i].sport[j] == 'P')
                outfile <<"Posing: ";
            outfile << setw(10) << scrlist[i].score[j] << endl;
            total1 = total(total1, scrlist);
            outfile << "Total: " <<setw(15) << total << endl;
            if(total2<total1)
            {
                total2=winner;
                contestant=scrlist[i].athletenum;
            }

        }
    }
    outfile << "Athlete of the Year: " << contestant << "With a total score of: " << winner << endl;
    outfile << " Computer Science Rocks!!!!!!!" << endl;
}
//gets total scores
//This is one of two functions that I could not get to work 
 //it is something wrong with my parameters
double total(double total1, Athletes scrlist[100])
{
    for(int i=0; i<100; i++)
    {

        for (int j=0; j<5; j++)
        {
            total1 =0;
            total1 = total1 + scrlist[i].score[j];
        }
    }

    return total1;
}

Edited 3 Years Ago by Reverend Jim: Fixed formatting

Please use code tags [code] //code goes here [/code]

Can you post a few lines of the input file?

One thing I noticed is if you have an error with the file, you keep right on processing the data. You need some sort of exit condition or a reprompt of the user to get a new filename (this could even take place within your openfiles). I'm not sure this is the issue at hand, though.

I'd recommend checking everything step by step. Make a one line file, and make sure it loads. Then try to read it in, checking each element as it's read. Then, get the whole file read in if you can. At that point you can think about incorporating the other functions. It sounds like it will be more time consuming, but I think in the end it will save you a lot of time.

Edited 5 Years Ago by jonsca: n/a

Heres a piece of the input file....

4
G 8.9
P 7.5
S 7.8
D 5.5
B 8.6
13
P 8.5
G 8.6
D 6.5
S 6.9
B 8.3
7
P 8.5
G 8.7
B 8.4
D 6.9
S 6.2

Sorry, I guess those are the athlete numbers.

Change

while(scrlist[i].athletenum)

to

while(infile>>scrlist[i].athletenum)

That way you can skip having to read once before the loop, and once you run out of lines the loop will stop right away.

Edited 5 Years Ago by jonsca: n/a

well I did as you suggested and changed...

while(scrlist[i].athletenum)

to...

while(infile>>scrlist[i].athletenum!= -1)

but I get an error message saying: binary '!=' : no operator found which takes a right-hand operand of type 'int'

You don't need anything in the while loop, as infile is returning an istream reference, not the value of the input variable. Once it runs out of items, it goes to null and stops the loop.

Is there an actual line with the number -1 on it, or are you talking about EOF? If you need it to wait for an actual athlete number of -1, then still use the infile to drive the loop, but check for an athlete number equal to -1 and break out of the while loop when you hit it.

while(infile >> scrlist[i].athletenumber)
{
    if(scrlist[i].athletenumber == -1)
        break;
}

It's not dramaticaly different than what you had before, but I think it's a little more robust.

ok I realize that this is getting repetitive and thanks again for your help. When I added your code everything compiles just fine, and I guess moves to the next function which is printcontestants. But doesn't print anything, it's like it skips over it.

Put some cout statements in the body of the function at different points to see how much of it gets executed. Check the output file, too, to see if anything is written. You never actually check to see if it opened successfully, so put in a statement or two to check that.

ok things happened, in the function printcontestants in the first for loop if I change

for(int i=0; i<count; i++)
//in which count is the number of athlete numbers read in from the file

to...

for(int i=0; i<7; i++)
//7 is the number of athlete numbers read in from file
but I can't keep it at 7 because the program is supposed to run no matter the amount
of input.

this is my output...

Kenley O'Brien
CMPS 2 Program 1
4-9.25596e+061
-9.25596e+061
-9.25596e+061
-9.25596e+061
-9.25596e+061
Total:               0
-858993460-9.25596e+061
-9.25596e+061
-9.25596e+061
-9.25596e+061
-9.25596e+061
Total:               0
-858993460-9.25596e+061
-9.25596e+061
-9.25596e+061
-9.25596e+061
-9.25596e+061
Total:               0

... and so forth

any thoughts?

Edited 3 Years Ago by mike_2000_17: Fixed formatting

ok things happened, In the function printcontestants when I changed the first for loop from...

for(ini i=0; i<count; i++)
//in which count is the number of athlete numbers read in

to...

for(int i=0; i<7; i++)
//but I can't leave it at 7 because the program is supposed to work no matter the amount of input

this is my output...
CMPS 2 Program 1
4-9.25596e+061
-9.25596e+061
-9.25596e+061
-9.25596e+061
-9.25596e+061
Total: 0
-858993460-9.25596e+061
-9.25596e+061
-9.25596e+061
-9.25596e+061
-9.25596e+061
Total: 0
-858993460-9.25596e+061
-9.25596e+061
-9.25596e+061
-9.25596e+061
-9.25596e+061
Total: 0


...and so forth

Those values are coming from uninitialized float variables. Did you print out the structs in getathletes to make sure everything's coming in okay?

I think you may want to keep a count of the number of athletes in getathletes that you can pass to the other functions so you're not dumping out a largely empty array when you output to file.

Other than that, I haven't discovered anything else so far.

i did keep a counter in getathletes, thats what the variable count is for, and I just pass it to the other functions when needed. Ill keep try to print out somewhere else

There's no variable count in the code that you posted before. "i" can really double as the count, but the other functions aren't aware of it, so you're dumping 90 some odd entries that are not valid.

I think ive isolated the problem to the for loop in the getathletes fuction. The function reads in the first value which is 4 and prints it, but when it moves into the loop its just garbage. Anything you can see wrong with storing the information with that for loop? Or maybe with my declaration of the struct or the array?

Post up that section of your code (just that function) again, as I think you might have left one too many infile statements in there.

void getathletes(ifstream & infile, Athletes scrlist[MAXSIZE], int i, int count)
{
	i=0;
	count=0;
	
	while(infile >> scrlist[i].athletenum)
	{
		 
			infile >> scrlist[i].athletenum;
			for(int j=0; j<5; j++)
				{
					
					infile >> scrlist[i].sport[j];
					infile >> scrlist[i].score[j];

				}
			i++;
			count++;
			if(scrlist[i].athletenum == -1)
				break;
	}
	
}

Yeah, you don't want line 9 in there. That will give you an extra read that you don't want.

Move lines 19 and 20 up to line 8 so that if you reach that condition, you'll exit the loop straight away (you could even combine it with the loop condition like

while(infile >> scrlist[i].athletenum && scrlist[i].athletenum != -1)

Double check that to make sure it behaves like you want it to).

WOW holy shit that actually fixed it, you are amazing. You should get paid for doin this. Pisses me off that it was one line that was givin me all of that trouble. Thanks again man you are awesome

No problem. I had fixed it on mine when I edited your code, but I didn't think to check and make sure you'd fixed it the same way. Hehe.

This article has been dead for over six months. Start a new discussion instead.