Thread: ARg!

  1. #1
    Registered User
    Join Date
    Apr 2003
    Posts
    31

    ADVICE!

    I'm designing a student class that reads from a file for the name, ID, grade, and courses[first and second semester]. The file will look like this:

    Joe Blog,45478,9
    Math,89,78
    Science,78,89
    ;
    Andy Allen,00012,12
    Science,89,48
    Math,78,69
    History,88,90
    ;


    As you are see, the name, id, and grade are on the same line, separated by a comma. Then the next lines iare the courses and first and second semester grades in percent. Finally each student is separated by a semicolon. For the final output, I'm to display their schedule and grades for both semesters, and sort the students by their overall GPA!

    I'm planning to use struct for the name, ID number, grade, and grades(which will then be a 2 X 6 array), and courses (array of size 6--the maximum number of courses)

    And I'm thinking of using Vectors for storing all the students' information. Any other efficient ideas?

    Any advices on how to do this in the most effective way?
    Last edited by Aakash Datt; 06-01-2003 at 12:16 AM.

  2. #2
    Registered User
    Join Date
    Dec 2002
    Posts
    56
    The actual code would take a little testing to work out the details, but the basic idea would go like this:

    vector<student> theStudents;

    while(!END_OF_FILE) { // using whatever EOF test you want, some are flawed

    student theStudent; // your 'student' structure

    1) use std::getline to take in the first line (you may even want to use the form that takes a delimeter (like ',') so you don't have to do that later). Store the pieces to variables in theStudent;

    2) for int i from 0 to 5, use std::getline to take in another line (once again, possibly using the delimeter form so you don't have to parse it after) and store the pieces to structures in theStudent.classes[i]

    3) Take in one more line, and verify that it's a semicolon. If not, you have an error condition (are there always six classes?). If it is, ignore it anyway.

    4) theStudents.push_back( theStudent );

    Just an idea. That's how I'd do it. (Actually, it's how I did it, with a problem pretty similar.)

  3. #3
    Registered User
    Join Date
    Apr 2003
    Posts
    31
    1) use std::getline to take in the first line (you may even want to use the form that takes a delimeter (like ',') so you don't have to do that later). Store the pieces to variables in theStudent;
    How do I do that?
    Also, I can't seem to make struct work in a class...where should I put it?

  4. #4
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    I would create a Student class that has data members for firstname, lastname, id, grade, and Node* firstcourse.

    Each Node would have two data members: a struct Course, and a Node* pointing to the next node (or null if the Student has no more courses to record).

    Each Course would consist of coursename, grade1, grade2.

    Read in the data using an outer loop to read in the name, id and grade and create the Student, and an inner loop that reads in the course info, exiting when it encounters ";".

  5. #5
    Registered User
    Join Date
    Apr 2003
    Posts
    31
    What's a node?

  6. #6
    Registered User
    Join Date
    Nov 2002
    Posts
    126
    What might be better, as for parsing information from the file, is to just separate name, ID, and grade with whitespace instead of commas. That way, you could just use the cin >> operator to read each one into a string variable(string object, not char*). This method might give you a little more flexibility as well.

    Each Node would have two data members: a struct Course, and a Node* pointing to the next node (or null if the Student has no more courses to record).
    Why make your own half-ass list when the STL already has plenty of useful containers. Yes, a vector could be a good way to store each student struct. A list or queue might also be useful

  7. #7
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    A node is part of a linked list. Don't worry about it if you haven't studied linked lists.

    "Also, I can't seem to make struct work in a class...where should I put it?"

    Don't use structs. In C++ , you use classes, and except for the default access specifier, in C++ there is no difference between structs and classes.
    Code:
    class AnotherClass;
    
    class Student
    {
        public: 
            Student(){};
            ....
            ....
        private:
            ...
             AnotherClass a;
    };
    
    class AnotherClass
    {
    ...
    ...
    };
    
    int main()
    {
    
    ...
    
    return 0;
    }
    getline()
    One definition of getline(), in the header <string>, takes 3 parameters: the stream, the variable, and the delimiter

    getline(inFile, string_var, ',');

    That version of getline() will read from inFile into the string type "string_var" until a comma is encountered. The comma will be removed from the stream, but not read into the variable. (There is also a version of getline() for char arrays that is similar.)
    Last edited by 7stud; 05-31-2003 at 06:56 PM.

  8. #8
    Registered User
    Join Date
    Apr 2003
    Posts
    31
    Misunstanding

    The file must be in the following format:
    Joe Blog,45478,9
    Math,89,78
    Science,78,89
    ;
    Andy Allen,00012,12
    Science,89,48
    Math,78,69
    History,88,90
    ;

    That's what's difficult--there's a comma separating each thing (no space) and the first line is different from the second one...and there can be up to 6 classes.
    Last edited by Aakash Datt; 06-01-2003 at 12:15 AM.

  9. #9
    Registered User
    Join Date
    Dec 2002
    Posts
    56
    Originally posted by Aakash Datt
    How do I do that?
    First, look up std::getline(). It takes three parameters: the input stream, the destination (using a string would be your best bet), and the delimeter (optional, because it defaults to '\n').

    For example:
    Code:
    ifstream in( "somefile.dat" );
    string data;
    std::getline( in, data, ',' );
    // this reads the file up to the first comma, and puts it into "data"
    Repeat this process for each of the pieces of data you need. Except, instead of declaring the string "data" as I did in the example above, it will already be declared as part of the structure you're using.

    Code:
    struct student {
      string name;
      int id_number;
      // etc.
    };
    
    std::getline( in, name );
    It does get slightly more complicated when you have a line like:
    Science 89, 48

    if the 89 is not part of the name of the course. This is because part of it is delimited by whitespace, and part by commas. First, I'd use the >> operator to read the name of the class (as long as its always 1 word). Then you could use getline to read until the next comma, but before that you would probably want to call cin.ignore() to skip the space. You store the "89" in a string (or char*) and use atoi() on it to convert it to a number before storing it in some_student.id_number.

    If all this seems too complicated, it's really a bunch of nitpicky things. The problem is that the input file format isn't very regular, or easy to work with. Good luck, and I hope this helps.

  10. #10
    Registered User
    Join Date
    Apr 2003
    Posts
    31
    If I don't use struct, how else can I store their information such as grade, id number, grade, and course? Also, can I have an array inside a struct?
    Last edited by Aakash Datt; 06-01-2003 at 12:26 AM.

  11. #11
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    "Also, can I have an array inside a struct?"

    Hmmm...would that take more than 2 minutes to test? You can have anything you want inside a struct, except another member of the same struct.

    "If I don't use struct, how else can I store their information such as grade, id number, grade, and course?"

    100 different variables, arrays, or classes.

    "That's what's difficult--there's a comma separating each thing (no space)"

    It doesn't matter in the slightest whether a comma or a space is the separator.

    "...and the first line is different from the second one..."

    Which doesn't matter at all either as long as all the first lines are the same--and they are.

    "...and there can be up to 6 classes."

    That's the tricky part, but that's where the semicolons help you out. They signal the start of a new student. If you read comma to comma, then you'll have to deal with the situation when you try to read in the last piece of data for a student. This is what you'll get:

    89
    ;
    John Jones

    I guess you could search every string you read for a semicolon and if you find one in the string, then you know you've hit the end of the information for a student, and the current string has the format above, and using string functions you could extract the substring before and after the semicolon. That means all your reads have to be into string variables in first place and you have to convert the strings that have the numbers in them to ints.

    Or, you could read from semi-colon to semi-colon, and then extract the substrings between commas and convert the appropriate ones to ints.

    How you store them is not that big a deal. You can use classes(or structs) or arrays.
    Last edited by 7stud; 06-01-2003 at 03:45 AM.

  12. #12
    Registered User
    Join Date
    Apr 2003
    Posts
    31

    This doesn't work :(

    Code:
    #include <iostream>
    #include <fstream>
    #include <sstream>
    using namespace std;
    
    int main()
    {
    	string filename = "words.txt";
    	ifstream input;
    	input.open(filename.c_str());
    
    	string s;
    	while(getline(input, s, ';'))
    	{
    		cout<<s;
    	}
    	
    
    	return 0;
    }
    Gives...

    Joe Blog,45478,9
    Math,89,78
    Science,78,89

    Andy Allen,00012,12
    Science,89,48
    Math,78,69
    History,88,90
    Press any key to continue

    What's the next step I should do?
    Last edited by Aakash Datt; 06-01-2003 at 04:45 PM.

  13. #13
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    Not surprising.

    First, when you post code, type:
    [ code]
    your code goes here
    [ /code]
    but leave out the blank spaces following the "["

    now here:
    while (input.get(ch))
    you read the next character in the file. What happens to that character if it is not a ";"? (it's gone)

    and here:
    getline(input, s, ',');
    problem is that the lines of your input file don't end with ","

    I suggest you try using getline(input, buffer) to read the input file one full line at a time. (This "buffer" is just an ordinary string to hold the input temporarily.) If buffer == ';' you know it's time to move to another student. Otherwise, buffer contains data for the current student. Try using string functions to parse it into the individual data fields.

  14. #14
    Registered User
    Join Date
    Dec 2002
    Posts
    56
    The getline using ',' for a delimiter was my suggestion because I figured if you knew that the file always contained something like "some_data, some_other_data, some_third_data" on each line, you could read it by fields (separated by commas rather than newlines). I still think I would do it that way, but it's probably not as easy to see, so it may be better to just read the whole line and tokenize it somehow (I never used strtok).

  15. #15
    Registered User
    Join Date
    Apr 2003
    Posts
    31
    How do I separate the student from the ID from the grade using getline?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pointer to struct
    By Paul Johnston in forum C Programming
    Replies: 4
    Last Post: 06-11-2009, 03:01 AM
  2. Replies: 10
    Last Post: 06-08-2009, 02:42 PM
  3. Replies: 5
    Last Post: 08-12-2007, 05:26 PM
  4. Ranged numbers
    By Desolation in forum Game Programming
    Replies: 8
    Last Post: 07-25-2006, 10:02 PM
  5. Compiler "Warnings"
    By Jeremy G in forum A Brief History of Cprogramming.com
    Replies: 24
    Last Post: 04-24-2005, 01:09 PM