question on c++ program using structs/classes

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • gdarian216
    New Member
    • Oct 2006
    • 57

    question on c++ program using structs/classes

    I have written a c++ program that takes input from a file and outputs the average. The program uses structs and I need to convert the struct to a class.

    I just dont know how to get started and if I will have to re-write my whole program.

    Code:
    #include <cstdlib>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <fstream>
    using namespace std;
    
    ifstream in_file;
    //structure that holds student record information.
    typedef struct records{
            string name;
            float quizes[7];
            float projects[6];
            float exams[2];
            float labs[14];
    };
    
    const int num_quizes = 7;
    const int num_exams = 2;
    const int num_projects = 6;
    const int num_labs = 14;
    
    const int quizes_pts = 70;
    const int exams_pts = 200;
    const int projects_pts = 300;
    const int labs_pts = 150;
    
    void get_scores(ifstream& infile, int num_scores, float scores[]);
    double get_average(float scores[], int num_scores, int tot_pts, float& average);
    void total_average(float average,float& student_average);
    void grades_display(int counter,float ave1,float ave2,float ave3,float ave4,float total,char grade);
    
    
    
    int main()
    {
    
    
                cout << "No.   Name      Quiz   Project   Exam   Lab   Total   Grade"
             << endl;
        cout << "        --- ---------   ----- ---------- ------ ----- -------  -----"
             << endl;
        cout << endl;
    
    
            records grades;
            ifstream in_file;
            // Define a file input stream and open the file
            in_file.open("record.txt"); //opening file
    
            if (in_file.fail())
            {
            // Failed to open the file (file doesn't exist or isn't readable)
            cout << "Could not open file: "<< "\n";
            exit(1);
            }
            float average = 0;
            int counter = 1;
            while(!in_file.eof())
            {
            //get string from the file
            in_file >> grades.name;
    
    
    
            char letter_grade;
            float student_average = 0;
    
    
            // Repeatedly get characters from the file
    
            get_scores(in_file, num_quizes, grades.quizes);   //function for inputing info in struct.
            get_average(grades.quizes, num_quizes, quizes_pts, average); //function for average
            total_average(average,student_average);
            float quiz_average = average;
    
            get_scores(in_file, num_projects, grades.projects); //input project scores
            get_average(grades.projects, num_projects, projects_pts, average);
            total_average(average,student_average);
            float project_average = average;
    
            get_scores(in_file, num_exams, grades.exams); //input exam scores
            get_average(grades.exams, num_exams, exams_pts, average);
            total_average(average,student_average);
            float exams_average = average;
    
            get_scores(in_file, num_labs, grades.labs); //input lab scores
            get_average(grades.labs, num_labs, labs_pts, average);
            total_average(average,student_average);
            float labs_average = average;
    
            student_average = student_average/4;
            grades_display(counter,quiz_average,project_average,exams_average,labs_average,student_average,letter_grade);
    
            counter++;
    }
    
    
            // Close the file
        in_file.close();
    
    
        return 0;
    }
    
    
    
    //function that takes in parameters to input scores in array
    void get_scores(ifstream& in_file, int num_scores, float scores[])
    {
    
            for (int i = 0; i < num_scores; i++)
            {
             in_file >> scores[i];
    
            }
    
    }
    
    //funtion that takes the average of the inputed scores
    double get_average(float scores[], int num_scores,int tot_pts,float& average)
    {
         float a = 0;
    
         for (int i = 0; i < num_scores; i++)
         {
            a = scores[i] + a;
         }
            average = (a/tot_pts);
            average = average * 100;
    
            return average;
    }
    
    //function to take total average for each member
    void total_average(float average,float& student_average)
    {
    
            student_average  = average + student_average;
    
    }
    
    //function to output letter grade and output scores
    void grades_display(int counter,float ave1,float ave2,float ave3,float ave4,float total,char grade)
    {
    
            if(90 < total)
               grade = 'A';
            if((80 < total)&&(total < 90))
               grade = 'B';
            if((70 < total)&&(total < 80))
               grade = 'C';
            if((60 < total)&&(total < 70))
               grade = 'D';
            if (total < 60)
               grade = 'F';
    
            cout << "         " << counter << "        "  << ave1  << "     " << ave2  << "     " << ave3  << "     " << ave4 << "     " << total << "    " << grade;
    
    
    
    }

    would it be easier to put the class program in separate files
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    Just start with your struct:

    Code:
    struct records{
            string name;
            float quizes[7];
            float projects[6];
            float exams[2];
            float labs[14];
    };
    ;

    and put your member function names inside the struct:

    Code:
    struct records{
            string name;
            float quizes[7];
            float projects[6];
            float exams[2];
            float labs[14];
    
             void get_scores(ifstream& in_file, int num_scores, float scores[]);
    
    };
    Then code the function as:
    Code:
    //function that takes in parameters to input scores in array
    void records::get_scores(ifstream& in_file, int num_scores, float scores[])
    {
    
            for (int i = 0; i < num_scores; i++)
            {
             in_file >> scores[i];
    
            }
    
    }
    Then make the data private and the function public:

    Code:
    struct records{
         private:
            string name;
            float quizes[7];
            float projects[6];
            float exams[2];
            float labs[14];
         public:
             void get_scores(ifstream& in_file, int num_scores, float scores[]);
    
    };
    Re-compile and verify everything is still working.

    Finally, just change struct to class and tou are done.

    Code:
    class records{
         private:
            string name;
            float quizes[7];
            float projects[6];
            float exams[2];
            float labs[14];
         public:
             void get_scores(ifstream& in_file, int num_scores, float scores[]);
    
    };
    You can now start removing function arguments that are member data.

    Finally, add your constructors.

    It turns out in C++ that there really are no classes. The underlying implementation is a struct with public/private/protected members. In fact, the only differende between a struct and a class is that the DEFAULT access spoecificer for a struct is public whereas the default for a class is prviate. If you specify public/private/protected for each of your struct members, then there is no difference between a struct and a class.

    Comment

    • gdarian216
      New Member
      • Oct 2006
      • 57

      #3
      You can now start removing function arguments that are member data.

      Finally, add your constructors.

      It turns out in C++ that there really are no classes. The underlying implementation is a struct with public/private/protected members. In fact, the only differende between a struct and a class is that the DEFAULT access spoecificer for a struct is public whereas the default for a class is prviate. If you specify public/private/protected for each of your struct members, then there is no difference between a struct and a class.[/QUOTE]

      if I remove the arguments in my functions that are member data how will my code work, would I just have to not use functions?

      Comment

      • gdarian216
        New Member
        • Oct 2006
        • 57

        #4
        if I remove the arguments in my functions that are member data how will my code work, would I just have to not use functions?

        if my member arrays are private and I have a function that will add the values to my arrays. how can I then pass those values on to the other functions that need them or am I able to do that. ..Im really not sure of how to implement what I'm trying to do.

        Comment

        • gdarian216
          New Member
          • Oct 2006
          • 57

          #5
          i guess my problem is that since my input is coming from a file Im having a hard time figuring out how to code that for a class since I can just set the values of my string and arrays at the beginning. And after I set the values in my class array how would I pass the values to the other functions that need them?

          Comment

          • weaknessforcats
            Recognized Expert Expert
            • Mar 2007
            • 9214

            #6
            Let's start at this point:
            Code:
            //function that takes in parameters to input scores in array
            void records::get_scores(ifstream& in_file, int num_scores, float scores[])
            {
            
                    for (int i = 0; i < num_scores; i++)
                    {
                     in_file >> scores[i];
            
                    }
            
            }
            Here the target array is a private member of the class. To load the projects array write a member fuction to load it using the above function as a pattern:
            Code:
            //function that takes in parameters to input projects in array
            void records::set_projects(ifstream& in_file)
            {
            
                    for (int i = 0; i < 6; i++)
                    {
                     in_file >> projects[i];
            
                    }
            
            }
            You don't need the pointer to the array because this function only does the projects array and you don't need the number of elements in the array becuse you have hard-coded the 6 in the class definition. Just create a member function to load each of your arrays and other member functions to access the array members.

            I realize that you will have several functions that are mostly identical exceot fior the array name and the array size.

            Comment

            • gdarian216
              New Member
              • Oct 2006
              • 57

              #7
              okay I got that now lets say i have created these

              Code:
              public:
                      void set_name(ifstream& in_file);
                      void set_quizes(ifstream& in_file);
                      void set_projects(ifstream& in_file);
                      void set_exams(ifstream& in_file);
                      void set_labs(ifstream& in_file);
              and this is the one for the string member

              Code:
              void records::set_name(ifstream& in_file)
              {
                      in_file >> name;
              }
              I then want to pass the string to another function to output it in a display.
              I have loaded the array values but how can they be used by another function?

              is it by passing records::quizes as an argument

              Comment

              • weaknessforcats
                Recognized Expert Expert
                • Mar 2007
                • 9214

                #8
                The "another function" will have to be a member function since the arrays are private. So you have:

                Code:
                void records::show_projects()
                {
                      for (int i = 0; i < 6; i++)
                        {
                         cout << projects[i];
                
                        }
                 
                }
                This will show all 6 projects.

                If you need the value of a specific project, then you need a member function for that purpose:

                Code:
                float records::get_project(int val)
                {
                      //might be good to check val between 0 and 5 here to avoid a crash
                      return projects[val]; 
                }

                That is, no function outside the class has access to the array. Those external functions call member functions of records to get the information you need. The idea is that the member functions will protect the projects array and keep it from getting screwed up.

                Comment

                • gdarian216
                  New Member
                  • Oct 2006
                  • 57

                  #9
                  so for the most part the functions that need to use my class members should go in the public part. and then the other functions should be okay

                  Comment

                  • weaknessforcats
                    Recognized Expert Expert
                    • Mar 2007
                    • 9214

                    #10
                    The public functions are the class interface (an API if you will). These functions protect the private data from hackers an other evildoers. They also have the advantage that should the class need to be redesigned (which happens a lot) and if you can keep the function prototypes unchaned, then the only functions needing modification will be the member functions. To use your new design the class customers would only need to recompile.

                    This is why you are to never have public data.

                    Now, a function needing access to private data is out of luck unless there is a class member function that can provde the necessary data. You just don't put any old function inside the class.

                    So here is a function to display the project values:

                    Code:
                    //num is the project to display:
                    void display_projects(records* obj, in num)
                    {
                          for (int i = 0; i < 6; i++)
                            {
                             cout << i << ". " << obj-> get_project(i);
                    
                            }
                     
                    }
                    This line:

                    obj-> get_project(i);

                    is the call to the member function

                    int records::get_pr oject(int value);

                    You DO NOT put the display_project s function in the records class as a member.

                    Comment

                    Working...