Thread: How to calculate grades using Linked Lists

  1. #1
    Registered User
    Join Date
    Jun 2009
    Posts
    9

    How to calculate grades using Linked Lists

    Code:
    Here are the program details:
    
    1. Modify the grading program from project 12 such that:
    
    1) The program uses the same grading policy. The program will read in the students’ scores.
    
    2) The program should be built around a linked list of structures instead of an array of structures. The structure will contain an additional member (a pointer to the next node). Store a student’s information in a dynamically allocated structure.
    
    3) There should not be a limit on the size of the database. Use malloc to allocate memory for a new structure. 
    
    4) Before the program terminates, print a listing of all students in the database, showing their names, scores on quizzes and tests, and their numeric score for the entire course.
    
    Name         Quiz1 Quiz2 midterm Final Total
    Mike Fisher   8      9        89         98    92.5
    Jon Stewart  7     8        78          84     80.5
    …
    
    5) Before the program terminates, display the average of the quizzes, tests, and the total score.
    
               Quiz1 Quiz2 midterm Final Total
    Average 7.5   8.5    83.5         91 86.375 …
    
    For some odd reason, a segmentation error is popping up as soon as I say n (for no). Also, I would like to be able to display the previous names and grades that I put in the loop. I am not sure how to. Any help ASAP would be appreciated. Thank you.
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #define NAME_LEN 50
    
    
    int read_line(char str[], int n);
    void insert (int num_students);
    void average_finder(int num_students);
    void print (int num_students);
    
    struct test_result {
    char name[NAME_LEN+1];
    int number;
    int grade1;
    int grade2;
    int midterm;
    int final;
    float numeric;
    struct test_result *next;
    };
    
    struct test_result *studen = NULL;
    
    
    int main(void)
    {
    
    struct test_result *p;
    
    char code = 'y';
    int num_students = 0;
    int done = 0;
    
    while(!done) {
    switch (code) {
    case 'y': insert(num_students);
    print(num_students);
    break;
    case 'n': average_finder(num_students); done++;
    return 0;
    
    default: printf("Invalid entry. Try again.\n");
    return 0;
    }
    
    
    printf("\nWould you like to enter another record? y(yes) or n(no)?");
    scanf(" %c", &code);
    
    while (getchar() != '\n'); /* skips to end of line */
    }
    
    return 0;
    }
    
    
    void insert(int num_students)
    {
    //int part_number = 0;
    
    struct test_result *p;
    
    p = malloc(sizeof(struct test_result)); 
    
    printf("Enter the student name: ");
    read_line(p->name, NAME_LEN);
    
    printf("Enter the student's grade for quiz #1: ");
    scanf("%d", &p->grade1);
    
    printf("Enter the student's grade for quiz #2: ");
    scanf("%d", &p->grade2);
    
    printf("Enter the student's grade for midterm: ");
    scanf("%d", &p->midterm);
    
    printf("Enter the student's grade for final: ");
    scanf("%d", &p->final);
    
    p->numeric = (((p->grade1 + p->grade2) * 1.25) + (p->midterm * 0.25) + (p->final * 0.50));
    
    }
    
    void average_finder(int num_students)
    {
    
    num_students = 0;
    
    struct test_result *p;
    
    int total_quiz1 = 0;
    int total_quiz2 = 0;
    int total_midterm = 0;
    int total_final = 0;
    int total_numeric = 0; 
    float average_quiz1 = 0;
    float average_quiz2 = 0;
    float average_midterm = 0;
    float average_final = 0;
    float average_numeric = 0;
    
    total_quiz1 += p->grade1 += num_students;
    total_quiz2 += p->grade2 += num_students;
    total_midterm += p->midterm += num_students;
    total_final += p->final += num_students;
    total_numeric += p->numeric += num_students;
    
    average_quiz1 = (double)total_quiz1 / num_students;
    average_quiz2 = (double)total_quiz2 / num_students;
    average_midterm = (double)total_midterm / num_students;
    average_final = (double)total_final / num_students;
    average_numeric = (double)total_numeric / (num_students);
    
    printf(" Quiz1 Quiz2 Midterm Final Total\n");
    printf("Average %9.1f %9.1f %9.1f %9.1f %9.3f\n", average_quiz1, average_quiz2, average_midterm, average_final, average_numeric);
    
    }
    
    void print(int num_students)
    {
    struct test_result *p;
    
    printf("Name Quiz1 Quiz2 Midterm Final Total\n");
    printf("%10s %9d %9d %9d %9d %9.1f\n", p->name, p->grade1, p->grade2, p->midterm, p->final, p->numeric);
    } 
    int read_line(char str[], int n)
    {
    int ch, i = 0;
    
    while(isspace(ch = getchar()))
    ;
    str[i++] = ch;
    while ((ch = getchar()) != '\n') {
    if (i < n)
    str[i++] = ch;
    }
    str[i] = '\0';
    return i;
    }

  2. #2
    pwning noobs Zlatko's Avatar
    Join Date
    Jun 2009
    Location
    The Great White North
    Posts
    132
    Your average_finder doesn't work because struct_test result* p does not point to anything valid when you start using it. The p must be the root of your linked list. You need to pass the root into your average_finder. Your insert needs to add the malloced memory to the root of the linked list. Finally, you need to increment num_students somewhere.
    What are you trying to do with this?
    total_quiz1 += p->grade1 += num_students;

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    1) Don't put your question inside the code tags! ONLY put the code inside there!
    2) INDENT YOUR CODE, for heaven's sake.
    You are not the only one who has to read this.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    How many times has this same question been asked?

  5. #5
    Registered User
    Join Date
    Jun 2009
    Posts
    9
    Alright, I enclosed the code, but I am still getting a segmentation fault.


    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #define NAME_LEN 50
    
    
    int read_line(char str[], int n);
    void insert (int num_students);
    void average_finder(int num_students);
    void print (int num_students);
    
    struct test_result {
        char name[NAME_LEN+1];
        int number;
        int grade1;
        int grade2;
        int midterm;
        int final;
        float numeric;
        struct test_result *next;
    };
    
    struct test_result *studen = NULL;
    
    
    int main(void)
    {
    
    struct test_result *p;
    
    char code = 'y';
    int num_students = 0;
    int done = 0;
    
    while(!done) {
    switch (code) {
    case 'y': insert(num_students);
    print(num_students);
        
    
    break;
    case 'n': average_finder(num_students); done++;
    return 0;
    
    default: printf("Invalid entry. Try again.\n");
    return 0;
    }
    
    
    printf("\nWould you like to enter another record? y(yes) or n(no)?");
    scanf(" %c", &code);
    
    while (getchar() != '\n'); /* skips to end of line */
    }
    
    return 0;
    }
    
    
    void insert(int num_students)
    {
     
        struct test_result *p;
    
        p = malloc(sizeof(struct test_result));   
        
        printf("Enter the student name: ");
        read_line(p->name, NAME_LEN);
    
        printf("Enter the student's grade for quiz #1: ");
        scanf("%d", &p->grade1);
    
        printf("Enter the student's grade for quiz #2: ");
        scanf("%d", &p->grade2);
    
        printf("Enter the student's grade for midterm: ");
        scanf("%d", &p->midterm);
    
        printf("Enter the student's grade for final: ");
        scanf("%d", &p->final);
    
        p->numeric = (((p->grade1 + p->grade2) * 1.25) + (p->midterm * 0.25) + (p->final * 0.50));
    
    }
    
    void average_finder(int num_students)
    {
    
        num_students = 0;
    
        struct test_result *p;
      
        int total_quiz1 = 0;
        int total_quiz2 = 0;
        int total_midterm = 0;
        int total_final = 0;
        int total_numeric = 0; 
        float average_quiz1 = 0;
        float average_quiz2 = 0;
        float average_midterm = 0;
        float average_final = 0;
        float average_numeric = 0;
       
         total_quiz1 += p->grade1;
         total_quiz2 += p->grade2;
         total_midterm += p->midterm;
         total_final += p->final;
         total_numeric += p->numeric;
         
        average_quiz1 = total_quiz1 / num_students;
        average_quiz2 = total_quiz2 / num_students;
        average_midterm = total_midterm / num_students;
        average_final = total_final / num_students;
        average_numeric = total_numeric / num_students;
    
    printf("              Quiz1      Quiz2   Midterm    Final     Total\n");
        printf("Average  %9.1f %9.1f %9.1f %9.1f   %9.3f\n", average_quiz1, average_quiz2, average_midterm, average_final, average_numeric);
    
    }
    
    void print(int num_students)
    {
        struct test_result *p;
    
        printf("\n");
    
        printf("Name               Quiz1      Quiz2   Midterm    Final     Total\n");
        printf("%10s %9d %9d %9d %9d   %9.1f\n", p->name, p->grade1, p->grade2, p->midterm, p->final, p->numeric);
    }
    
        
    int read_line(char str[], int n)
    {
    int ch, i = 0;
    
    while(isspace(ch = getchar()))
    ;
    str[i++] = ch;
    while ((ch = getchar()) != '\n') {
    if (i < n)
    str[i++] = ch;
    }
    str[i] = '\0';
    return i;
    }

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Alright, I enclosed the code, but I am still getting a segmentation fault.
    When?

    You need to learn how to troubleshoot your issues. Find the spot you're at in the code when it generates the error, and you're off to a pretty good start. What is it you're doing when it faults?


    Quzah.
    Hope is the first step on the road to disappointment.

  7. #7
    pwning noobs Zlatko's Avatar
    Join Date
    Jun 2009
    Location
    The Great White North
    Posts
    132
    If struct test_result *studen is the root of your linked list, then you need to place the malloc'd students on that root. The insert routine does not do that. Why are you passing num_students to insert? I can guess what you are trying to do, but I'd like you to explain it. It will help you think through the problem.

  8. #8
    Registered User
    Join Date
    Jun 2009
    Posts
    9
    The program I am working on an update of a prior project that I did using structs. In that program, I was able to use num_students as a array number, which allowed me to average each quiz, test and numeric score based on the number of students I entered.

    Here is the struct program:

    Code:
    #include <stdio.h>
    #include <ctype.h>
    #define NAME_LEN 50
    #define STUD_LEN 100
    
    
    int read_line(char str[], int n);
    void insert (int student_number);
    void print (int num_students);
    void average_finder(int num_students);
    
    
    struct test_result {
        char name[NAME_LEN+1];
        int number;
        int grade1;
        int grade2;
        int midterm;
        int final;
        float numeric;
    }studen[STUD_LEN];
    
    int main(void)
    {
    
        char code = 'y';
        int num_students = 0;
        for (num_students = 0; num_students < STUD_LEN; num_students++) {
    
    
            switch (code) {
            case 'y': insert(num_students);
                      print(num_students);
             break;
            case 'n': average_finder(num_students);
             return 0;
    
            default: printf("Invalid entry. Try again.\n");
             return 0;
            }
    
           
           printf("\nWould you like to enter another record? y(yes) or n(no)?");
            scanf(" %c", &code);
    
           while (getchar() != '\n') /* skips to end of line */
             ;
          
        }
    return 0;
    }
    
    void insert(int num_students)
    {
       int part_number = 0;
    
       studen[num_students].number = part_number;
    
        printf("Enter the student name: ");
        read_line(studen[num_students].name, NAME_LEN);
    
        printf("Enter the student's grade for quiz #1: ");
        scanf("%d", &studen[num_students].grade1);
    
        printf("Enter the student's grade for quiz #2: ");
        scanf("%d", &studen[num_students].grade2);
    
        printf("Enter the student's grade for midterm: ");
        scanf("%d", &studen[num_students].midterm);
    
        printf("Enter the student's grade for final: ");
        scanf("%d", &studen[num_students].final);
    
        studen[num_students].numeric =
        (((studen[num_students].grade1 + studen[num_students].grade2) * 1.25) + (studen[num_students].midterm * 0.25) + (studen[num_students].final * 0.50));
    
    }
    
    void average_finder(int num_students)
    {
      
        int i;
        int total_quiz1 = 0;
        int total_quiz2 = 0;
        int total_midterm = 0;
        int total_final = 0;
        int total_numeric = 0; 
        float average_quiz1 = 0;
        float average_quiz2 = 0;
        float average_midterm = 0;
        float average_final = 0;
        float average_numeric = 0;
        for (i = 0; i < num_students ;i++)  {
            total_quiz1 += studen[i].grade1;
            total_quiz2 += studen[i].grade2;
            total_midterm += studen[i].midterm;
            total_final += studen[i].final;
            total_numeric += studen[i].numeric;
         }
    
        average_quiz1 = (double)total_quiz1 /(num_students);
        average_quiz2 = (double)total_quiz2 / (num_students);
        average_midterm = (double)total_midterm / (num_students);
        average_final = (double)total_final / (num_students);
        average_numeric = (double)total_numeric / (num_students);
        printf ("The average score on quiz 1 is %.1f\n", average_quiz1);
        printf ("The average score on quiz 2 is %.1f\n", average_quiz2);
        printf ("The average score on midterm is %.1f\n", average_midterm);
        printf ("The average score on final is %.1f\n", average_final);
        printf ("The average score for the entire course is %.1f\n", average_numeric);
        
    
     
     
    }
    
    void print(int num_students)
    {
        printf("\n");
        printf("%s's score for the entire course is %.1f\n", studen[num_students].name, studen[num_students].numeric );
    
    }
    
    int read_line(char str[], int n)
    {
    int ch, i = 0;
    
    while(isspace(ch = getchar()))
    ;
    str[i++] = ch;
    while ((ch = getchar()) != '\n') {
    if (i < n)
    str[i++] = ch;
    }
    str[i] = '\0';
    return i;
    }

  9. #9
    pwning noobs Zlatko's Avatar
    Join Date
    Jun 2009
    Location
    The Great White North
    Posts
    132
    OK but you're not using arrays anymore. When you had arrays, your num_students was updated in a loop in the main program. You no longer have such a loop, and you no longer need num_students in insert because you're not inserting into an array, so you should clean that up. You still need to keep track of num_students somehow but only to calculate averages. I suggest that you increment num_students in the while(!done) loop in main.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Singly Linked Lists: Clarification Needed
    By jedispy in forum C++ Programming
    Replies: 4
    Last Post: 12-14-2006, 05:30 PM
  2. Linked Lists 101
    By The Brain in forum C++ Programming
    Replies: 5
    Last Post: 07-24-2004, 04:32 PM
  3. Map file formats and linked lists
    By Spitball in forum Game Programming
    Replies: 2
    Last Post: 03-04-2004, 11:32 PM
  4. need help w/ linked lists
    By MKashlev in forum C++ Programming
    Replies: 11
    Last Post: 08-05-2002, 08:57 PM
  5. doubly linked lists
    By qwertiop in forum C++ Programming
    Replies: 3
    Last Post: 10-03-2001, 06:25 PM