Having problems incrementing variable names

This is a discussion on Having problems incrementing variable names within the C++ Programming forums, part of the General Programming Boards category; I am trying to complete my first C++ Project and I can't seem to figure out how to do the ...

  1. #1
    Registered User
    Join Date
    Nov 2001
    Posts
    3

    Having problems incrementing variable names

    I am trying to complete my first C++ Project and I can't seem to figure out how to do the following:

    I am fin information from a file that looks like this:
    Fname Lname (strings)
    NumofGrades (int)
    Grade1 Grade2 GradeN (doubles)

    The file the instructor will be using can have any number of grades and students (The program is supposed to read from the file and print the student's name and average. I can fin the file and cout the information but how can I take multiple grades and users into consideration? Here is the code that I have compiled (with 0 errors). Can anyone put me on the right track??

    #include<iostream>
    #include<fstream>
    using namespace std;


    ///////////////////////////////////
    // Structures //
    ///////////////////////////////////

    struct student{
    char name[128];
    int NumofGrades;
    double Grade1, Grade2, Grade3, Grade4, Grade5;
    };


    ///////////////////////////////////
    // Prototypes //
    ///////////////////////////////////

    void ReadStudent(istream &in, student &e);
    void WriteStudent(ostream &out, student &e);


    ///////////////////////////////////
    // Main //
    ///////////////////////////////////

    int main(){

    ifstream in;
    in.open("program1.dat");
    if(in.fail()){
    cout<<"Error opening file!!!"<<endl;
    return(0);
    }

    student e1;
    student e2;
    student e3;
    student e4;
    ReadStudent(in, e1);
    ReadStudent(in, e2);
    ReadStudent(in, e3);
    ReadStudent(in, e4);
    WriteStudent(cout, e1);
    WriteStudent(cout, e2);
    WriteStudent(cout, e3);
    WriteStudent(cout, e4);



    return(0);
    }



    ///////////////////////////////////
    // Definitions //
    ///////////////////////////////////

    void ReadStudent( istream &in, student &e) {

    char pbuf[128];
    in>>e.name;
    strcat(e.name, " ");
    in>>pbuf;
    strcat(e.name, pbuf);


    in >>e.NumofGrades
    >>e.Grade1 >>e.Grade2 >>e.Grade3 >>e.Grade4 >>e.Grade5;

    }

    void WriteStudent(ostream &out, student &e) {
    out << "Name: " << e.name << endl;
    out << "# of grades:" << e.NumofGrades << endl
    << "Grades: " << e.Grade1 <<" "<< e.Grade2 <<" "
    << e.Grade3 <<" " << e.Grade4 <<" " << e.Grade5 << endl ;
    double average;
    average= (e.Grade1+e.Grade2+e.Grade3+e.Grade4+e.Grade5)/e.NumofGrades;
    out<< "Average:" << average << endl << endl;
    }

  2. #2
    Registered User
    Join Date
    Aug 2001
    Posts
    155
    According to specifications listed you don't need to hang onto anything as you will be printing the information to the screen/file as soon as you get it, therefore you don't need a struct at all.

    Since you don't have to hang onto the individual grades for any reason you don't need individual variables to hold them. You can just add the value of a given grade to each preceding grade. Theerefore I would replace the grade variables with a variable called grade, a second variable called total, and a third variable called average.

    Since you will do the same steps over and over and over for each new student in the file, a loop to repeat the process for each student seems like a nice idea.

    Since you don't know how many students will be represented in the file you need to know when to quit reading the file. Usually it is when you come to the end of the file which can be detected in several different ways, such as while(in) or while(!in.eof()), etc.

    Presumably your instructor has discussed various aspects of file handling with you. To be able to read a file you need to know exactly how it is set up. It helps if you created the file because then you know exactly how it is set up. If you didn't create it, then someone has to tell you. Is the name on a separate line from the number of grades which is on a separate line from the grades which are all on the same line, or what. If there is more than one item on a line are the space separated or comma separated or separated by some other indicator?

    Since you will be given the number of grades for a given student you can use a loop to read all the grades in for that student one at a time adding each new grade to the previous total.

    Assuming space delimited data here is some psuedocode:

    char name[128];
    int i, num;
    double grade, total, average;

    ifstream...

    while(ifstreamName)
    {
    in >> name; /If you need to use names like John Doe you need to use getline() rather than >>.
    in >> num;

    total = 0;
    for(i = 0; i < num; i++)
    {
    in >> grade;
    total += grade;
    }

    //if you use getline() to read in the name you should use in.ignore(); here.

    average = total/num;

    cout << name << ' ' << average << endl;
    }

  3. #3
    Registered User
    Join Date
    Nov 2001
    Posts
    30
    >#include<iostream>
    >#include<fstream>
    >using namespace std;


    >///////////////////////////////////
    >// Structures //
    >///////////////////////////////////


    Btw, here's a little something for future reference:

    typedef struct student_typ {
    // struct members, like name, grades, etc
    } student, *student_ptr;

    Helps ya keep track of your struct pointers and the structs themselves

    >struct student{
    >char name[128];
    >int NumofGrades;

    You said it can take any number of grades. Use an array, just a suggestion.

    #define MAX_GRADES 100
    // if you haven't learned the above yet, perhaps the following
    // const int MAX_GRADES 100;
    double grade[MAX_GRADES] ;

    This still wouldn't take any number, but for your "first project" I don't think
    you'd would be required to dynamically allocate memory for additional grades.

    >double Grade1, Grade2, Grade3, Grade4, Grade5;
    >};


    >///////////////////////////////////
    >// Prototypes //
    >///////////////////////////////////

    >void ReadStudent(istream &in, student &e);
    >void WriteStudent(ostream &out, student &e);


    >///////////////////////////////////
    >// Main //
    >///////////////////////////////////

    >int main(){

    >ifstream in;
    >in.open("program1.dat");
    >if(in.fail()){
    >cout<<"Error opening file!!!"<<endl;

    Furture reference: Might wanna return some sort of error exit code
    ie. return(IN_OPEN)
    where IN_OPEN is a const or define of some non 0 number. Zero usually
    means the program exited with no fatal run time errors.
    >return(0);
    >}

    Looking at what you have below I think you only need to define 1 student and reuse it. I'll give you an example of what you could do below, but if you really want 4 student type vars., make an array of students, much neater.

    student e[MAX_STUDENTS];
    or just
    student e;

    If you use the first one you still won't be able to store unlimited student records, but again, I don't think they would require something like that in a first assignment.

    >student e1;
    >student e2;
    >student e3;
    >student e4;

    Ah, now I see. I should have read ahead. You won't need an array at all, and you don't need to store each record individually. Just reuse the same student variable.

    A for or while loop would work here, probably for would be best.
    If input fails while trying to read a student's record, then in.fail() will be set to true. This will occur if you've reached the end of file marker. You can't tell if you got no record or a partial record. Since you may want to warn the user if there is a partial record you'll have to modify ReadStudent(). Perhaps read a peice of data, check for error, read a string a character at a time, checking for failure after each read. I'll leave that up to you.

    while(!in.fail()) {
    ReadStudent(in, e); // Read a student record
    if(!in.fail())
    WriteStudent(in, e); // Write record to standard output
    }

    The above will eliminate the next 8 lines of code
    >ReadStudent(in, e1);
    >ReadStudent(in, e2);
    >ReadStudent(in, e3);
    >ReadStudent(in, e4);
    >WriteStudent(cout, e1);
    >WriteStudent(cout, e2);
    >WriteStudent(cout, e3);
    >WriteStudent(cout, e4);



    >return(0);
    >}



    >///////////////////////////////////
    >// Definitions //
    >///////////////////////////////////

    >void ReadStudent( istream &in, student &e) {


    >char pbuf[128];
    >in>>e.name;
    >strcat(e.name, " ");
    >in>>pbuf;
    >strcat(e.name, pbuf);


    >in >>e.NumofGrades

    Use a for loop here. That way you can handle "any number of grades."
    Also, make sure NumofGrades has not exceeded the maximum number of grades, that would be nasty.

    for(int i=0; i< e.NumofGrades && i< MAX_GRADES; i++)
    in>>e.grade[i];
    // Now get the \n
    char cr;
    in >> cr;

    Oh yeah, if NumofGrades > MAX_GRADES, you'll want to change NumofGrades
    to MAX_GRADES, for computing average later. If you know how a>b?x:y works, I would change the above for statement (just because I like obscure code) to this:

    for(int i = 0; i < (e.NumofGrades = (e.NumofGrades > MAX_GRADES ?
    MAX_GRADES : e.NumofGrades)); i++)...

    If you don't know what that does, LOOK IT UP. Just kidding, just do something like this:

    if(e.NumofGrades > MAX_GRADES)
    e.NumofGrades = MAX_GRADES;

    >>>e.Grade1 >>e.Grade2 >>e.Grade3 >>e.Grade4 >>e.Grade5;

    >}

    >void WriteStudent(ostream &out, student &e) {
    >out << "Name: " << e.name << endl;
    >out << "# of grades:" << e.NumofGrades << endl

    Again, for loop here.

    for(int i=0; i< e.NumofGrades; i++)
    out << e.grade[i] << " ";
    out << endl;

    ><< "Grades: " << e.Grade1 <<" "<< e.Grade2 <<" "
    ><< e.Grade3 <<" " << e.Grade4 <<" " << e.Grade5 << endl ;
    >double average;

    Another for loop

    for(int i=0; i<e.NumofGrades; i++)
    average += e.grade[i];
    average /= e.NumofGrades;

    >average= >(e.Grade1+e.Grade2+e.Grade3+e.Grade4+e.Grade5)/e.NumofGrades;
    >out<< "Average:" << average << endl << endl;
    >}

    BAM, you're done. Well, I'm done...touch up that crappy code I just wrote

  4. #4
    Registered User
    Join Date
    Nov 2001
    Posts
    3
    Thanks for the help. Everything is working great now.

  5. #5
    Registered User matheo917's Avatar
    Join Date
    Sep 2001
    Posts
    279

    little hint...

    just for future reference....

    if you use <fstream> as your header file, you don't need to include <iostream> anymore.... b/c <fstream> has <iostream> declared with in itself....

    good luck....

    Regards,
    matheo917

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Variable names starting with _
    By edesign in forum C Programming
    Replies: 3
    Last Post: 06-05-2009, 04:47 AM
  2. How to manage variable and function names
    By jefflieu in forum C++ Programming
    Replies: 14
    Last Post: 02-07-2008, 03:33 AM
  3. Question about printing a variable???
    By Hoser83 in forum C++ Programming
    Replies: 2
    Last Post: 03-31-2006, 01:57 PM
  4. problems with passing ostream variable
    By paperbox005 in forum C++ Programming
    Replies: 2
    Last Post: 07-31-2004, 01:31 AM
  5. variable names
    By trekker in forum C Programming
    Replies: 3
    Last Post: 03-16-2002, 03:37 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21