Generate data to be used to test the main algorithm
Here's some code to write a binary file containing date and temperature values (a necessary precursor to writing code to read such data):
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int day;
int month;
float max_temp;
float min_temp;
} Date;
int main(void)
{
const char filename[] = "Metriseis_2012.dat";
FILE *fp = fopen(filename, "wb");
if (fp == NULL)
{
fprintf(stderr, "Failed to open file '%s' for writing\n", filename);
exit(EXIT_FAILURE);
}
for (int i = 0; i < 30; i++)
{
Date D =
{
.day = rand() % 28 + 1, .month = rand() % 12 + 1,
.min_temp = rand() % 20,
};
D.max_temp = rand() % 50 + D.min_temp;
printf("Day temperature: %6.2f - %6.2f on %.2d-%.2d\n", D.min_temp, D.max_temp, D.month, D.day);
if (fwrite(&D, sizeof(D), 1, fp) != 1)
{
fprintf(stderr, "failed to write to '%s'\n", filename);
exit(EXIT_FAILURE);
}
}
fclose(fp);
return 0;
}
The data generation code does not preclude repeats in the date (and indeed, the dates 02-08
and 08-01
both repeat in the sample data, with different temperature ranges). Fixing that is moderately hard. The generated data is not sorted into date order.
The separate assignment to D.max_temp
avoids running foul of the indeterminate evaluation order specified in C11 §6.7.9 Initialization ¶23:
The evaluations of the initialization list expressions are indeterminately sequenced with respect to one another and thus the order in which any side effects occur is unspecified.152)
152) In particular, the evaluation order need not be the same as the order of subobject initialization.
You could add:
#include <time.h>
and (at the top of main()
):
srand(time(0));
so that it generates different sequences of numbers when it is called no more frequently than once a second. There are other, better ways to seed the random number generator, but they involve more code (and often some platform specific code too).
Determine minimum and maximum temperatures and corresponding dates
Here's code that reads the data and determines the date on which the minimum temperature was recorded (and the minimum value), and the date on which the maximum temperature was recorded (and the maximum value).
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int day, month;
float max_temp, min_temp;
} Date;
int main(void)
{
const char filename[] = "Metriseis_2012.dat";
FILE *fp = fopen(filename, "rb");
if (fp == NULL)
{
fprintf(stderr, "Failed to open file '%s' for reading\n", filename);
exit(EXIT_FAILURE);
}
Date Dmin = { 0, 0, 100.0, 100.0 };
Date Dmax = { 0, 0, 0.0, 0.0 };
Date D;
while (fread(&D, sizeof(Date), 1, fp) == 1)
{
printf("Day temperature: %6.2f - %6.2f on %.2d-%.2d\n", D.min_temp, D.max_temp, D.month, D.day);
if (D.max_temp > Dmax.max_temp)
Dmax = D;
if (D.min_temp < Dmin.min_temp)
Dmin = D;
}
fclose(fp);
printf("Min temperature: %6.2f on %.2d-%.2d\n", Dmin.min_temp, Dmin.month, Dmin.day);
printf("Max temperature: %6.2f on %.2d-%.2d\n", Dmax.max_temp, Dmax.month, Dmax.day);
return 0;
}
On my Mac, the output I got from the reading code was:
Day temperature: 13.00 - 21.00 on 02-08
Day temperature: 4.00 - 32.00 on 09-07
Day temperature: 0.00 - 15.00 on 02-16
Day temperature: 7.00 - 10.00 on 03-01
Day temperature: 0.00 - 12.00 on 02-24
Day temperature: 9.00 - 16.00 on 02-12
Day temperature: 19.00 - 47.00 on 10-09
Day temperature: 17.00 - 43.00 on 08-01
Day temperature: 10.00 - 43.00 on 08-01
Day temperature: 19.00 - 40.00 on 02-08
Day temperature: 13.00 - 49.00 on 09-28
Day temperature: 8.00 - 49.00 on 06-10
Day temperature: 1.00 - 4.00 on 02-07
Day temperature: 8.00 - 48.00 on 05-01
Day temperature: 10.00 - 13.00 on 09-17
Day temperature: 9.00 - 33.00 on 11-27
Day temperature: 17.00 - 25.00 on 02-02
Day temperature: 18.00 - 49.00 on 02-17
Day temperature: 5.00 - 19.00 on 02-20
Day temperature: 5.00 - 24.00 on 01-08
Day temperature: 9.00 - 10.00 on 11-28
Day temperature: 5.00 - 9.00 on 12-02
Day temperature: 8.00 - 31.00 on 07-04
Day temperature: 12.00 - 28.00 on 11-26
Day temperature: 18.00 - 62.00 on 10-21
Day temperature: 11.00 - 39.00 on 10-06
Day temperature: 17.00 - 64.00 on 03-14
Day temperature: 9.00 - 40.00 on 01-27
Day temperature: 15.00 - 63.00 on 04-18
Day temperature: 8.00 - 20.00 on 08-03
Min temperature: 0.00 on 02-16
Max temperature: 64.00 on 03-14
There are two entries for the minimum temperature — the first is selected. A more complex test could choose the earliest date or latest date.
It would be sensible to have the generator program accept command line arguments that specify the output file name and a number of output records to generate. The analyzer program should accept command line arguments that specify the file name(s) to be processed.