Detailed Examination of a CSV File – Solution

The task for this month’s Exercise is to read a CSV file, store the data, then manipulate and report. For my solution, I chose to create an array of structures in which to store the weather information.

Here is the nested structure I used in my solution:

struct calendar {
    int year;
    char *month;
    int day;
};
struct temperature_data {
    struct calendar date;
    float high;
    float low;
};

I could have put all the data into a single-level structure, but whenever I see a date as part of the data, I create a nested structure. Above, the calendar structure has year, month, and day members. The month member is a pointer, which references an array of month strings. It could have easily been a char array instead.

The structure is defined externally, which allows all the program’s various functions to access the temperature_data struct variable. In the main() function, a structure array is declared:

struct temperature_data winter[RECORDS];

As with last month’s Solution, the CSV file is read, but this time its values are stored in the winter[] array. The file is closed, and a series of printf() statements coupled with various functions generate the required output.

Here’s sample output from my solution:

Date range from December 25, 2016 to January 24, 2017:
The average high was 29.16
The average low was 14.48
The highest high was 41.0 on January 20, 2017
The lowest high was 16.0 on January 3, 2017
The highest low was 32.0 on January 22, 2017
The lowest low was -3.0 on January 12, 2017

The first line simply pulls the date from the first and last elements of the winter[] array:

    printf("Date range from %s %d, %d to %s %d, %d:\n",
            winter[0].date.month,
            winter[0].date.day,
            winter[0].date.year,
            winter[RECORDS-1].date.month,
            winter[RECORDS-1].date.day,
            winter[RECORDS-1].date.year
            );

The RECORDS constant is set to 31, the number of records in the weather_data.csv file. This first date is found in element zero of the array; the last date is at the value RECORDS minus one.

The next six lines of output rely upon six functions I wrote to manipulate the data:

float average_high(struct temperature_data w[]);
float average_low(struct temperature_data w[]);
int highest_high(struct temperature_data w[]);
int lowest_high(struct temperature_data w[]);
int highest_low(struct temperature_data w[]);
int lowest_low(struct temperature_data w[]);

The first two functions calculate the average temperatures for the weather[].high and weather[].low members of the structure array, represented as w[] inside the functions.

Remember: You must declare the temperature_data structure before you prototype the functions!

The remaining functions crunch the numbers to return the specific element number for the minimum and maximum values as required. The element number is used to generate the output that shows the temperature and date.

The highest/lowest functions are pretty basic, with subtle changes between each one to get the specific values. I wrote the first one, highest_high(), and then copied-and-pasted it to help create the others.

To view my entire solution, click here. It’s long: 233 lines, but again the final four functions are similar.

Your solution doesn’t need to be identical to mine. If your output matches the results shown earlier in this post, you’re good.

Leave a Reply