Expiring Today—Celebrate National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

replace code and create functions (rush!)

Posted on 2004-04-11
14
Medium Priority
?
420 Views
Last Modified: 2010-04-01
Experts,

Okay, I am 'just' learning C++ and up until now have been doing great with my assignments (yes, this is a class).  Here is, only 3 weeks left for the course, and this chapter really threw me for a loop (no pun intended) and I'm confused on how to create functions for certain tasks.

I wrote a simple program that calculates GPA averages for university students.  It works -- all is good.  I now have to remove a lot of the code and replace with functions.  I've been reading and trying different things for the past 3 hours, and nothing is working.  I need some guidance here...

The new functions I have to create are:

Function OpenFiles:
opens the input and output files, sets the output of the floating point nubmers to two decimal places in a fixed decimal format with a decimal point and trailing zeros

Function initialize:
initializes variables - countFemale, countMale, fsumGPA, msumGPA

Function sumGrades
find the sums of femail and make students GPAs

Function averageGrade:
finds the average GPA for female and male students

Function printResults:
output the releveant results.

Note:  cannot use global variables.  need to use the appropriate parameters to PASS information in/out of the functions (so need a by ref functions)

I'm a mess cause I can get it to work.  Instead of sending you my 'mess', here is my original code, which I wrote and totally understand, but to get in my head to switch it all around is confusing (I could do one or two of these,....but not all of them at the same time...HELP!)


My code:

==========================================================================
#include <iostream.h>
#include <fstream.h> // required statement for file I/O
#include <iomanip.h> // required statement to use manipulators


int main()

{
int countFemale = 0; // variable for total of females
int countMale = 0; //variable for total of males
double msumGPA = 0.0; // variable for total male GPA
double fsumGPA = 0.0; //variable for total female GPA

char studentType; // variable stores whether male or female
double studentGPA =  0; // variable stores GPA to be used in calculations

ifstream infile;
ofstream outfile;

infile.open("a:GPA.txt"); // open input file

if(!infile) // if file is not found, then message displays and program shuts down
{
      cout<<"Cannot open input file"<<endl;
      cout<<"Program terminates!!"<<endl;
      return 1;
}

// file is found, and program continues

outfile.open("a:GPAdone.txt");
outfile.setf(ios::fixed,ios::floatfield);
outfile.setf(ios::showpoint);
outfile<<setprecision(2);

cout<<"Processing data...."<<endl;

infile>>studentType>>studentGPA;

while(infile)
{
      switch(studentType)// loops through and finds female or male and counts each separatly
      {
      case 'F':
      case 'f': fsumGPA = fsumGPA + studentGPA;
            countFemale++;
            break;

      case 'M':
      case 'm': msumGPA = msumGPA + studentGPA;
            countMale++;
            break;

      default: cout<<"Invalid Student Data"<<endl;
      } // end switch

      infile>>studentType>>studentGPA;

} // end while looping


//Output the results

outfile<<"The total number of female students is "<<countFemale<<endl;
outfile<<"The average GPA for female students is "<<fsumGPA/countFemale<<endl;
outfile<<endl;
outfile<<"The total number of male students is "<<countMale<<endl;
outfile<<"The average GPA for male students is "<<msumGPA/countMale<<endl;
outfile<<endl;
outfile<<"The total number of all students is "<<countFemale+countMale<<endl;
outfile<<"The average GPA for all students is "<<(fsumGPA + msumGPA)/(countFemale+countMale)<<endl;
outfile<<endl;

      return 0;

}
====================================================================
0
Comment
Question by:AliciaVee
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 5
  • 3
14 Comments
 
LVL 11

Expert Comment

by:bcladd
ID: 10801264
Okay, let's focus on the first function you are supposed to write, OpenFiles. What we want to do is identify the parameters you are going to need, the return type of the function, and had how you are going to call it.

It is supposed to open the input and output files. Without global variables (it is GOOD to use no global variables), the files that are opened must be parameters (when thinking about parameters, think about communication. What information must be communicated between the caller and the callee. Here we must communicate the open, established input and output streams FROM OpenFiles back TO main...). Since they are OUTPUT from the function, they have to be reference parameters (do you understand the difference between pass by value (passing a COPY into the function) and pass by reference (passing a reference to the original item)? If not, ask). Using your program as a model, we don't need any other information as the name of the input and output files are fixed as are the various settings. So the only communication is from the called function back to main passing the opened files.

Wait, a mistake in the previous statement: We should also communicate the success or failure of opening the two streams. Easiest way to do that? Have the function return a boolean value, true if the files are opened, false otherwise. That way you can check the return code in main, if it is false you can exit (as you do now if either of the files is not opened properly).

Does the analysis make sense? Given this description, we can write the signature of the function:

bool OpenFiles(ifstream & infile_param, ofstream & outfile_param)
{
  // DO SOME WORK HERE
}

Then, in main, we can imagine how to call the function:

if (!OpenFiles(infile, outfile)) {
  // HANDLE FAILURE (return 1)
}

Now, what goes into the function? All the code to open the files. That is the infile.open() line, the check for success, the outfile.open() line and the check for success there. Only differences: You want to return false rather than 1 if there is a problem; the names of the variables was changed (I added _param to the end so you can tell the difference when reading them; not strictly necessary but it can give you a heads up on where the variable came from) and the function must return true if it reaches the end (both of the success if statements return short of this so it will return false or true depending solely on the success of opening the two files).

I have spelled this one out. The others are similar in that you want to figure out what is being communicated, how it is communicated (into, out of or into and out of the function), and then how it is being calculated (what part of main you will be replacing with a call to your function). I would suggest just replacing one item at a time since you can compare the output with the original.

HTH, -bcl
0
 
LVL 44

Expert Comment

by:Karl Heinz Kremer
ID: 10801339
There is one thing bcladd did not talk about yet :-) which is required (you may get your program to work without is however).

You are already using one function: main() which already returns a status. You are not calling this function directly, it gets called by the operating system (actually by the program loader, or runtime linker). All you have to do now is pretty much like writing your main function - just a bit more complicated :-)

You don't have to tell the compiler about main(), because the linker "knows" that it has to be there. This can be shown by e.g. renaming the main() function to main_x(). If you compile your program again, you will end up with an error message.
When you create your own functions, the compiler doesn't know about them, so you have to "introduce" them to the compiler before you use them. You can actually just write them and use them without this "introduction" (or declaration), but this requires that you define them before they get used. The right way to handle this is however to declare the functions first. At the top of your program (right after the include statements), you would add these function declarations. If we take the function from bcl's example, the declaration would look like this:

bool OpenFiles(ifstream & infile_param, ofstream & outfile_param);

You see, it's exactly the same as the start of the function definition, just without the actual implementation. You need to end the declaration with a ';'

0
 

Author Comment

by:AliciaVee
ID: 10801388
bcladd,

Wow!  your explanation is quite thorough and just want I need to try and figure this out -- although, I thought I was doing what you mentioned, probably not in the right order.  its still confusing to me, but I'll do as you suggest and take one function at a time and see if I can get something to work.  The problem I have is that one function depends on another and am not sure how this is all going to work.  I tried doing it all at once, because I thought I had to reference the parameters, and I'm still not clear on the ref and val usage (this was all new in this chapter).  We haven't done functions at all yet...except for this unit, and trying to package them all in one program was hard for me to handle.

But, I'll re-read through your outline and see if I can get the concept.  stay tuned....

khk -- thanks for mentioning that....yes, this part was covered in our chapter and I will make sure I don't forget to incorporate that in.

AV
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 44

Expert Comment

by:Karl Heinz Kremer
ID: 10801415
You can start with the output function, this should not depend on any other function. All you need is a mechanism to pass in your data.

Your main function should call all your functions in the right order, so you should be able to do one after the other.

If you have something to show, just post your code here.

0
 

Author Comment

by:AliciaVee
ID: 10801477
khk,

thanks for your encouragement and road map.  Just starting on it....will be  a while I'm sure....

I'll be back.
:)

AV
0
 

Author Comment

by:AliciaVee
ID: 10801905
bcladd,

Sorry, althougth I would have loved to 'figure it out' I just cant, which is why I posted this.  I read what you said, and thought maybe it might help me see the light, but here I am, another 2 hours...and am not any close.

I am confused because:

I don't know where to declare the variables;
I don't know how to use the initiatlize function that I am requred to do;
I am confused on when to use a by ref, or a value, or a void fuction.

Please...I NEED MORE HELP.  AT this point, can you GIVE me the solution?.  I can learn a lot better if I see how it works, and then can understand the concept going forward.

Here is what I came up with, trying to move things around, and trying to figure out how to call a function by ref, by val, or void...initialize...its a mess!

Suprisingling, I only get 5 compile errors.  I dare not run it cause my PC might blow up!

#include <iostream.h>
#include <fstream.h> // required statement for file I/O
#include <iomanip.h> // required statement to use manipulators


//Function Prototypes
double sumGrades(ifstream& inp, double& fsumGPA, msumGPA);
bool openFiles;
void initialize (double& fsumGPA, msumGPA, tsumGPA, tsumStudents, int& countMale, countFemale);
void sumGrades(double& fsumGPA, msumGPA)



//this function initializes variables such as
//countFemale, countMale, fsumGPA, msumGPA
void initialize (double& fsumGPA, msumGPA, tsumGPA, tsumStudents, int& countMale, countFemale);
{

int countFemale = 0; // variable for total of females
int countMale = 0; //variable for total of males
double msumGPA = 0.0; // variable for total male GPA
double fsumGPA = 0.0; //variable for total female GPA
double tsumGPA=0;//totals both female and male GPA
ifstream myInFile;
ofstream myOutFile;

}

//in the main section, I will get and print the GPA

int main()


if(!OpenFiles) // if file is not found, then message displays and program shuts down
{
      cout<<"Cannot open input file"<<endl;
      cout<<"Program terminates!!"<<endl;
      return False;
}


      return 0;

}


//this function opens the input/output file, sets the output
//of the floating-point numbers to 2 decimal placed in a fixed
//format with a decimal point and trailing zeros

bool openFiles (ifstream& myInFile, ofstream& myOutFile)
{
      myInFile.open("a:GPA.txt"); // open input file

outfile.open("a:studentGradesdone.txt");
outfile.setf(ios::fixed,ios::floatfield);
outfile.setf(ios::showpoint);
outfile<<setprecision(2);

cout<<"Processing data...."<<endl;

}


//this function finds the sum GPA for female and male students
//Steps: read the input, get the input, print the GPA
void sumGrades(double& fsumGPA, msumGPA)

char studentType; // variable stores whether male or female
double studentGPA =  0; // variable stores GPA to be used in calculations

infile>>studentType>>studentGPA;

while(infile)
{
      switch(studentType)// loops through and finds female or male and counts each separatly
      {
      case 'F':
      case 'f': fsumGPA = fsumGPA + studentGPA;
            countFemale++;
            break;

      case 'M':
      case 'm': msumGPA = msumGPA + studentGPA;
            countMale++;
            break;

      default: cout<<"Invalid Student Data"<<endl;
      } // end switch

      infile>>studentType>>studentGPA;

} // end while looping


//this function finds the average GPA for female and male students
void averageGrade(double& fsumGPA, msumGPA)

{


      tsumStudents = countFemale+countMale;
      tsumGPA = (fsumGPA + msumGPA)/(countFemale+countMale)
}


//this function outpus the relevant results
//Steps: calculate the GPA, print the GPA
void printResults(double& averageGrade)

{

outfile<<"The total number of female students is "<<countFemale<<endl;
outfile<<"The average GPA for female students is "<<fsumGPA/countFemale<<endl;
outfile<<endl;
outfile<<"The total number of male students is "<<countMale<<endl;
outfile<<"The average GPA for male students is "<<msumGPA/countMale<<endl;
outfile<<endl;
outfile<<"The total number of all students is "<<tsumStudents<<endl;
outfile<<"The average GPA for all students is "<<tsumGPA<<endl;
outfile<<endl;

}

0
 
LVL 11

Expert Comment

by:bcladd
ID: 10801939
(1) No, I can't give you the solution. It is against the EE policy and against my own conscience.

(2) I will try to help you by answering your questions and helping you hunt down your bugs. This will take me a couple of minutes (need to compile your code).

-bcl
0
 
LVL 11

Accepted Solution

by:
bcladd earned 750 total points
ID: 10801996
The following address your compiler errors. Number after colon is the approximate line number.

gpa.cpp:8
double sumGrades(ifstream& inp, double& fsumGPA, msumGPA);
typename expected: Notice that there is no type for msumGPA. Assume it is double&

gpa.cpp:9
bool openFiles;
not actually a compiler error: If the function has parameters, include them in (); if there are no parameters, include the () so C++ knows it is a function.

gpa.cpp:10
void initialize (double& fsumGPA, msumGPA, tsumGPA, tsumStudents, int& countMale, countFemale);
typename expected: countFemale has no type

gpa.cpp:11
void sumGrades(double& fsumGPA, msumGPA)
typename expected:
Would you believe it took me to this point to realize the core problem? Declaring parameters for functions looks just like declaring variables but it isn't. You have to specify a type for each and every parameter. So the list consists of a type and a name for the parameter then a comma, a type and a name for the parameter. Should fix many errors.

Where to declare variables. This is a really good question. The answer is simple to state but sometimes hard to understand: Declare variables inside of the highest function where they are used. By height I mean in terms of calling. So if a variable is going to be used in main, initialize, and sumGrades, then it should be declared in main (main is called  by the OS and is called first. The other two are called directly from main so they are "lower"). You should pass the variable into the other functions as a parameter.

Here is the hard part, right? It looks like a parameter is a variable declaration and, for most purposes, it is. But, when passing things around as parameters, especially  reference parameters, we need one declaration of the actual variable and then we pass it in (and/or out) of other functions as a parameter so they can either use or set the value. So, for example, your initialize function has some logical problems. You should declare NO variables in initialize as all the variables will be passed in from main and have their values set in initialize. As in:

void initialize (double& fsumGPA, double & msumGPA,
                 double & tsumGPA, double & tsumStudents,
                 int& countMale, int & countFemale)
{
  countFemale = 0;
  countMale = 0;
  msumGPA = 0.0;
  fsumGPA = 0.0;
  tsumGPA=0;
} // initialize
/* I took the above from your code, cleaned up the indentation, removed a ; from after the ) in the parameter list (when defining the function you can't use the ; and when writing a prototype you MUST use the ;) and removed the type name in front of the variables inside the function. That way the PARAMETERS are set to the initial values. Since the streams are not passed in, there are not mentioned here. Now, in main() you must declare the variables and pass them as parameters to initialize*/
int main()
{
 
  int countFemale = 0; // variable for total of females
  int countMale = 0; //variable for total of males
  double msumGPA = 0.0; // variable for total male GPA
  double fsumGPA = 0.0; //variable for total female GPA
  double tsumGPA=0;//totals both female and male GPA
  ifstream myInFile;
  ofstream myOutFile;

  initialize(fsumGPA, msumGPA, tsumGPA, tsumStudents, countMale, countFemale);
  /* Notice that the order of the variables must match the order in the function's parameter list. This is important. The types must match in order but there is no requirement that the names match. */
  // ... and so on
} // main


Hope this helps,
-bcl
0
 
LVL 44

Assisted Solution

by:Karl Heinz Kremer
Karl Heinz Kremer earned 750 total points
ID: 10802143
There are a few more errors:

Your main function looks like this (blank lines removed):

//in the main section, I will get and print the GPA
int main()
if(!OpenFiles) // if file is not found, then message displays and program shuts down
{
     cout<<"Cannot open input file"<<endl;
     cout<<"Program terminates!!"<<endl;
     return False;
}
     return 0;
}

Your main function is missing the open brace:

int main()
{
    if (!OpenFiles)
    {
        ...
    }
    return 0;
}

Also, when you call OpenFiles, you are only checking a variable, and not calling a function, also C++ is case sensitive, so you need to name the function exactly like you defined it:

    if (!openFiles())
    {
        ...
    }

BTW: I share bcl's view of how to help with homework. You _HAVE_ to make these mistakes. This is the only way to learn. You are learning two things here: The C++ syntax (which is e.g. how to define a function and how to call it), but also "programming", which is way more than just the syntax of a language. It's the "feeling" for a language and how to solve programs in code. You can only learn this by making these mistakes and making them again in your next assignment, and again and again, until you finally "get" it. You need lots of practice, way more than you may realize right now.
0
 

Author Comment

by:AliciaVee
ID: 10802347
bcladd,

Wow...thanks -- really.  Okay, I was really stressing before, got a cup of java (like in coffee) and I feel I can spend more time to figure this out.  By the way -- I didn't know that EE cannot give help with homework assignments.  Makes sense I guess.

khk -- also much thanks to you too -- for your comments and explanations.

Back to my code....will be in touch soon.

:)
0
 

Author Comment

by:AliciaVee
ID: 10802699
Okay...  I'm done.

I guess both of you helped -- or at least tried to help me understand.  I'm still very confused.  It doesn't make sense to me, am sure I'm missing something.

I have to use an initialize function, to initialize variables, but I don't set them, and then I declare them again in main.  I don't see the value of using a function to initialize variables then?

its still not working...

but for now I'm done.  I can't get it....I think it was a lot to try and learn in one chapter jumping from learning a simple function to voids, ref, val, and all this other stuff for one assignment.

I'll take whatever credit I can and just wait till the teach marks up my assignment.

thanks in any event.

aliciaVee
0
 
LVL 44

Expert Comment

by:Karl Heinz Kremer
ID: 10802807
Show your code, we will certainly give you more input.

You need to understand the scope of variables. Your main function (hopefully) looks like this pseudo code:

int main()
{
    // variable declarations

    init(pass variables by reference);

    do_something_else(pass variables by reference or by value);

    return 0;
}

In this example you are first defining your (local) variables in your main routine. When you define them, the variables are _NOT_ initialized (that is as long as you are not using objects that have a constructor, but we leave this for some future homework :-). In order to initialize them, you pass them (by reference) into your init() function. Because they are passed by reference, the init() function can modify them. Once you return from the init() function, the local variables in your main() function are initialized. After that, you call some other functions that again can potentially modify your variables. You only pass those variables by reference that can be modified.
0
 

Author Comment

by:AliciaVee
ID: 10802910
Here is my code....am getting all kinds of errrors.

The assignment is due tomorrow, so maybe I need to sleep on it and start fresh tomorrow
:(

I really was doing so well in this class up until now.  just not getting it.

more reading and re-readigng I guess.

thanks,
AV

========================================================================

#include <iostream.h>
#include <fstream.h> // required statement for file I/O
#include <iomanip.h> // required statement to use manipulators


//Function Prototypes
void sumGrades(ifstream& myInFile, double& fsumGPA, double& msumGPA);
void openFiles (ifstream& myInFile, ofstream& myOutFile);
void sumGrades(double& fsumGPA, double& msumGPA);
void averageGrade(double& fsumGPA, double& msumGPA);
void printResults(ofstream& myOutFile, double& averageGrade);



//in the main section, I will get and print the GPA

int main()
{
 
  int countFemale; // variable for total of females
  int countMale; //variable for total of males
  double msumGPA; // variable for total male GPA
  double fsumGPA; //variable for total female GPA
  double tsumGPA; //totals both female and male GPA
  ifstream myInFile;
  ofstream myOutFile;

if(!openFiles) // if file is not found, then message displays and program shuts down
{
      cout<<"Cannot open input file"<<endl;
      cout<<"Program terminates!!"<<endl;
      return 1;
}

return 0;

}


//this function initializes variables such as
//countFemale, countMale, fsumGPA, msumGPA
void initialize (double& fsumGPA, double & msumGPA, double & tsumGPA, double & tsumStudents,
                         int& countMale, int & countFemale)
{
    fsumGPA = 0.0;
      msumGPA = 0.0;
      tsumGPA=0;
      tsumStudents = 0;
      countFemale = 0;
      countMale = 0;
}


//this function opens the input/output file, sets the output
//of the floating-point numbers to 2 decimal placed in a fixed
//format with a decimal point and trailing zeros

void openFiles (ifstream& myInFile, ofstream& myOutFile)
{
      myInFile.open("a:GPA.txt"); // open input file

myOutFile.open("a:studentGradesdone.txt");
myOutFile.setf(ios::fixed,ios::floatfield);
myOutFile.setf(ios::showpoint);
myOutFile<<setprecision(2);

cout<<"Processing data...."<<endl;

}


//this function finds the sum GPA for female and male students
//Steps: read the input, get the input, print the GPA
void sumGrades(double& fsumGPA, double& msumGPA)

char studentType; // variable stores whether male or female
double studentGPA =  0; // variable stores GPA to be used in calculations

infile>>studentType>>studentGPA;

while(myInFile)
{
      switch(studentType)// loops through and finds female or male and counts each separatly
      {
      case 'F':
      case 'f': fsumGPA = fsumGPA + studentGPA;
            countFemale++;
            break;

      case 'M':
      case 'm': msumGPA = msumGPA + studentGPA;
            countMale++;
            break;

      default: cout<<"Invalid Student Data"<<endl;
      } // end switch

      myInFile>>studentType>>studentGPA;

} // end while looping


//this function finds the average GPA for female and male students
void averageGrade(double& fsumGPA, double& msumGPA)

{

      fsumGPA = fsumGPA/countFemale;
      msumGPA = msumGPA/countMale;
      tsumStudents = countFemale+countMale;
      tsumGPA = (fsumGPA + msumGPA)/(countFemale+countMale);
}


//this function outpus the relevant results
//Steps: calculate the GPA, print the GPA
void printResults(double& averageGrade)

{

outfile<<"The total number of female students is "<<countFemale<<endl;
outfile<<"The average GPA for female students is "<<fsumGPA<<endl;
outfile<<endl;
outfile<<"The total number of male students is "<<countMale<<endl;
outfile<<"The average GPA for male students is "<<msumGPA<<endl;
outfile<<endl;
outfile<<"The total number of all students is "<<tsumStudents<<endl;
outfile<<"The average GPA for all students is "<<tsumGPA<<endl;
outfile<<endl;

}

0
 
LVL 44

Expert Comment

by:Karl Heinz Kremer
ID: 10802985
You are still not calling openFiles with the correct parameters.
The function sumGrades is declared twice, your implementation does not take the ifstream parameter (as it should, because you are using it). The fuction also is missing the top level braces. Also, you are using the wrong input stream variable when you read studentType and studentGPA.

you are using openFiles() in an if statement, but the function does not return any value. YOu need to change that.

There are more problems, but I don't have time right now to look further into this.
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

719 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question