Thread: C - Reading and iterating through data from file to calculate totals

  1. #1
    Registered User
    Join Date
    Oct 2020
    Posts
    11

    C - Reading and iterating through data from file to calculate totals

    I'm trying to implement a program that reads in data from a file called grad.dat. Each record (i.e. each line) in the data file gives statistics for a given country, year, degree, and gender, etc. The records are formatted as follows: <countryCode countryName gender degree year numGrads>


    Note: there are only 3 different types of degrees - L6, L7, and L8


    General format of grad.dat:
    Code:
        AUS Australia F L6 2010 1276
        AUS Australia M L6 2010 5779
        AUS Australia F L6 2011 1255
        AUS Australia M L6 2011 5739
        BEL Belgium F L6 2017 157
        BEL Belgium M L6 2017 1665
        BEL Belgium F L7 2010 61
        BEL Belgium F L8 2016 0
        BEL Belgium F L8 2017 1
        BEL Belgium M L8 2017 13
        BRA Brazil F L6 2010 7187
        BRA Brazil M L6 2010 32173
        BRA Brazil F L6 2011 6240
        BRA Brazil M L6 2011 30527
        BRA Brazil M L6 2014 30156
        BRA Brazil M L6 2016 32443
        CAN Canada F L6 2010 561
        CAN Canada F L6 2012 599
        CAN Canada M L6 2012 3018
    I'm trying to use this data to generate a series of reports. I'm stuck on the first report where I have to include:


    The graduate percentage for each country, by degree, for all years and all genders


    a. each country will be a row, and there will be a column for each type of degree, plus one column for
    all degrees combined


    b. each cell will show the proportion of graduates in that specific country, for that specific degree,
    compared to the total graduates in all countries combined, for that degree


    So generally, I want the first report to be printed like:
    Code:
        Country          L6         L7        L8       Total
        ----------------------------------------------------
        Country#1         %          %         %       
    
    
        Country#2         .....                         
    
    
        Country#3
    My program compiles. I'm required to store the graduate data in a linked list which I think I did correctly, but I'm having trouble with figuring out how to find the total number of graduates for all degrees in a specific country, as well as the total graduates in all countries combined, for that degree. My attempt at this is in report.c and I think I have the right idea of declaring variables for each degree (L6, L7, L8) and then adding the number of grads to the variable if the record's degree in the file matches the variable. I also think I have the right idea of finding the total number of graduates in a specific country by doing totalAllDegreesForCountry = L6+L7+L8.


    I'm running into issues where it keeps printing the same country multiple times as the country has multiple records in the file. I'm trying to figure out how to print each country only once. My program also seems to print all the records and then seg fault at the very end and I'm not sure why.


    I think the stats may be off too as it's printing values 1.00 and 0.00.


    I would really appreciate some help with this or a push in the right direction in getting my first report to print correctly.


    defs.h
    Code:
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
    
    
        #define MAX_STR 32
    
    
        typedef struct {
          char code[MAX_STR];
          char country[MAX_STR];
          char gender[MAX_STR];
          char degree[MAX_STR];
          int year;
          int numberOfGrads;
        } DataType;
    
    
        typedef struct Node {
          DataType *data;
          struct Node *prev;
          struct Node *next;
        } NodeType;
    
    
        typedef struct {
            int size;
            NodeType *head;
            NodeType *tail;
        } ListType;
        void initData(DataType**, char*, char*, char*, char*, int, int);
        void printData(const DataType*);
        void addDataToList(ListType*, DataType*);
        void printList(ListType*);
        void reportOne(ListType*);
    main.c
    Code:
        
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
    
    
        #include "defs.h"    
        int main()
        {
          FILE *infile;  
          DataType *data;
          ListType *list ;
          char code[MAX_STR];
          char country[MAX_STR];
          char gender[MAX_STR];
          char degree[MAX_STR];
          int year;
          int numberOfGrads;
          char input[MAX_STR];
    
    
          list->size = 0;
          list->head = NULL;
          list->tail = NULL;
    
    
          infile = fopen("grad.dat", "r");
          if (!infile) {
            printf("Error: could not open file\n");
            exit(1);
          }
          
          while (1) {
            fscanf(infile, "%s %s %s %s %d %d ", code, country, gender, degree, &year,  &numberOfGrads);
            initData(&data, code, country, gender, degree, year, numberOfGrads);
            addDataToList(list, data);
            if (feof(infile))
              break;
          }
          fclose(infile);
    
    
          while (1){
             printf(" 0. Quit \n");
             printf(" 1 = Top 5 and bottom 5 countries of female graduates \n");
    
    
            printf("Enter a selection: ");
            scanf("%s", input);  
    
    
            if(strcmp(input, "1")==0){
                reportOne(list);
            }else if(strcmp(input, "0")==0){
              break;
            }
          }
        }
    
    
        void initData(DataType **r, char *co, char *c, char *g, char *d, int y, int n){
            *r = malloc(sizeof(DataType));
            strcpy((*r)->code, co);
            strcpy((*r)->country, c);
            strcpy((*r)->gender, g);
            strcpy((*r)->degree, d);
            (*r)->year = y;
            (*r)->numberOfGrads = n;
        }
    
    
        void printData(const DataType *data){
            printf("%s %s %s %s %d %d\n", data->code, data->country, data->gender, data->degree, data->year, data->numberOfGrads);
        }
    
    
        void addDataToList(ListType *list, DataType *m){
          NodeType *currNode;
          NodeType *prevNode;
          NodeType *newNode;
    
    
          prevNode=NULL;
    
    
          int currPos = 0;
          currNode = list->head;
    
    
    
    
          while (currNode != NULL) {
            prevNode = currNode;
            currNode = currNode->next;
          }
    
    
          newNode = malloc(sizeof(NodeType));
          newNode->data = m;
          newNode->prev = NULL;
          newNode->next = NULL;
    
    
          if (prevNode == NULL)
            list->head = newNode;
          else
            prevNode->next = newNode;
    
    
          if (currNode == NULL)
            list->tail = newNode;
    
          newNode->next = currNode;
          newNode->prev = prevNode;
    
    
          if (currNode != NULL)
            currNode->prev = newNode;
          list->size++;
          }
    
    
        }
        void printList(ListType* list){
            NodeType *currNode = list->head;
            while(currNode != NULL){
                printData(currNode->data);
                currNode = currNode->next;
            }
        }
    reports.c
    Code:
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
    
    
        #include "defs.h"
    
    
        void reportOne(ListType* list){
          NodeType *currNode = list->head;
         
          float L6 = 0;
          float L7 = 0;
          float L8 = 0;
          
          float totalGradsCountry = 0; //specific country
          float totalGradsAll = 0; //all degrees all countries
          
          printf("%15s %10s %10s %10s %10s \n", "Country", "L6","L7","L8", "Total");
          printf("-------------------------------------------------------- \n");
    
    
          while (currNode != NULL) {
            if (strcmp(currNode->data->country, currNode->next->data->country) == 0){
                    if(strcmp(currNode->data->degree, "L6")==0){ 
                        L6 += currNode->data->numberOfGrads;
                    }else if(strcmp(currNode->data->degree,"L7")==0){
                        L7 += currNode->data->numberOfGrads;
                    }else if(strcmp(currNode->data->degree,"L8")==0){
                        L8 += currNode->data->numberOfGrads;
                    }
                    totalGradsCountry = L6 + L7 + L8;
                    totalGradsAll += totalGradsCountry;
              printf("%-15s %6.2f %6.2f %6.2f %7.2f \n", currNode->data->country, L6/totalGradsCountry, L7/totalGradsCountry, L8/totalGradsCountry, totalGradsCountry/totalGradsAll);
                }
            currNode = currNode->next;
          }
        }
    I have attached 2 pictures below to show of my output to show what I mean with the issues I'm facing

    C - Reading and iterating through data from file to calculate totals-pic1-jpgC - Reading and iterating through data from file to calculate totals-pic2-jpg
    Last edited by eagerissac; 12-10-2020 at 07:17 PM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,543
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 12-10-2020, 09:03 AM
  2. Replies: 16
    Last Post: 12-08-2017, 08:44 AM
  3. Replies: 13
    Last Post: 05-31-2009, 11:30 AM
  4. It is not reading the data from the file...
    By musique in forum C++ Programming
    Replies: 5
    Last Post: 05-01-2009, 03:19 PM
  5. Replies: 2
    Last Post: 06-16-2005, 10:03 AM

Tags for this Thread