Note: you can watch a video walkthrough of the solution to Between Days Whales List below.
int n_orca_pods = count_orca_sightings(first_pod); printf("%d Orca sightings in %s\n", n_orca_pods, argv[1]);Your task in this exercise is to complete this function:
int count_orca_sightings(struct pod *first_pod)
orca_list.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_SPECIES_NAME_LENGTH 4096
// a struct to represent the date
// a whale pod sighting was made
struct date {
int year;
int month;
int day;
};
// a struct to represent a sighting
// of a pod (group) of whales
struct pod {
struct pod *next;
struct date *when;
int how_many;
char *species;
};
struct pod *read_sightings_file(char filename[]);
struct pod *read_sighting(FILE *f);
struct date *read_date(FILE *f);
int count_orca_sightings(struct pod *first_pod);
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <file>\n", argv[0]);
return 1;
}
struct pod *first_pod = read_sightings_file(argv[1]);
int n_orca_pods = count_orca_sightings(first_pod);
printf("%d Orca sightings in %s\n", n_orca_pods, argv[1]);
return 0;
}
// return the number of sightings of Orca
int count_orca_sightings(struct pod *first_pod) {
int orca_count = 0;
struct pod *p = first_pod;
while (p != NULL) {
if (strcmp(p->species, "Orca") == 0) {
orca_count = orca_count + 1;
}
p = p->next;
}
return orca_count;
}
//
// DO NOT CHANGE THE FUNCTIONS BELOW HERE
//
// return linked list of sightings read from filename
// exit called if there is an error
struct pod *read_sightings_file(char filename[]) {
FILE *f = fopen(filename, "r");
if (f == NULL) {
fprintf(stderr,"error: file '%s' can not open\n", filename);
exit(1);
}
struct pod *first_sighting = NULL;
struct pod *last_sighting = NULL;
struct pod *sighting = read_sighting(f);
while (sighting != NULL) {
if (first_sighting == NULL) {
first_sighting = sighting;
first_sighting->next = NULL;
} else {
last_sighting->next = sighting;
}
last_sighting = sighting;
sighting = read_sighting(f);
}
return first_sighting;
}
// read a whale sighting (date, number of whales, whale species)
// return a pointer to a malloced struct containing these details
// return NULL if a sighting can not be read
struct pod *read_sighting(FILE *f) {
struct pod *p = malloc(sizeof (struct pod));
if (p == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
p->next = NULL;
p->when = read_date(f);
if (p->when == NULL) {
free(p);
return NULL;
}
int n_scanned = fscanf(f, "%d", &(p->how_many));
if (n_scanned != 1) {
free(p);
return NULL;
}
fgetc(f);
char species_buffer[MAX_SPECIES_NAME_LENGTH];
if (fgets(species_buffer, MAX_SPECIES_NAME_LENGTH, f) == NULL) {
free(p);
return NULL;
}
// finish string at '\n' if there is one
char *newline_ptr = strchr(species_buffer, '\n');
if (newline_ptr != NULL) {
*newline_ptr = '\0';
}
// also finish string at '\r' if there is one - files from Windows will
newline_ptr = strchr(species_buffer, '\r');
if (newline_ptr != NULL) {
*newline_ptr = '\0';
}
// malloc a char array long enough to hold species name
// and copy species to it
p->species = malloc(strlen(species_buffer) + 1);
if (p->species == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
strcpy(p->species, species_buffer);
return p;
}
// read a date in year/month/day format from stream f
// return a pointer to a malloced date struct containing them
// return NULL if a date can not be read
struct date *read_date(FILE *f) {
struct date *d = malloc(sizeof (struct date));
if (d == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
int n_scanned = fscanf(f, "%d/%d/%d", &(d->year), &(d->month), &(d->day));
if (n_scanned != 3) {
free(d);
return NULL;
}
return d;
}
void species_count(char species[], struct pod *first_pod, int *n_pods, int *n_whales) {
species_count_list.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_SPECIES_NAME_LENGTH 4096
// a struct to represent the date
// a whale pod sighting was made
struct date {
int year;
int month;
int day;
};
// a struct to represent a sighting
// of a pod (group) of whales
struct pod {
struct pod *next;
struct date *when;
int how_many;
char *species;
};
struct pod *read_sightings_file(char filename[]);
struct pod *read_sighting(FILE *f);
struct date *read_date(FILE *f);
void species_count(char species[], struct pod *first_pod, int *n_pods, int *n_whales);
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s <file> <species>\n", argv[0]);
return 1;
}
char *filename = argv[1];
char *species = argv[2];
struct pod *first_pod = read_sightings_file(filename);
int pod_count;
int whale_count;
species_count(species, first_pod, &pod_count, &whale_count);
printf("%d %s pods containing %d whales in %s\n", pod_count, species, whale_count, filename);
return 0;
}
// number of pods of the specified species assigned to *n_pods
// total number of whales of the specified species assigned to *n_whales
void species_count(char species[], struct pod *first_pod, int *n_pods, int *n_whales) {
int pods = 0;
int whales = 0;
struct pod *p = first_pod;
while (p != NULL) {
if (strcmp(p->species, species) == 0) {
pods = pods + 1;
whales = whales + p->how_many;
}
p = p->next;
}
*n_pods = pods;
*n_whales = whales;
}
//
// DO NOT CHANGE THE FUNCTIONS BELOW HERE
//
// return linked list of sightings read from filename
// exit called if there is an error
struct pod *read_sightings_file(char filename[]) {
FILE *f = fopen(filename, "r");
if (f == NULL) {
fprintf(stderr,"error: file '%s' can not open\n", filename);
exit(1);
}
struct pod *first_sighting = NULL;
struct pod *last_sighting = NULL;
struct pod *sighting = read_sighting(f);
while (sighting != NULL) {
if (first_sighting == NULL) {
first_sighting = sighting;
first_sighting->next = NULL;
} else {
last_sighting->next = sighting;
}
last_sighting = sighting;
sighting = read_sighting(f);
}
return first_sighting;
}
// read a whale sighting (date, number of whales, whale species)
// return a pointer to a malloced struct containing these details
// return NULL if a sighting can not be read
struct pod *read_sighting(FILE *f) {
struct pod *p = malloc(sizeof (struct pod));
if (p == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
p->next = NULL;
p->when = read_date(f);
if (p->when == NULL) {
free(p);
return NULL;
}
int n_scanned = fscanf(f, "%d", &(p->how_many));
if (n_scanned != 1) {
free(p);
return NULL;
}
fgetc(f);
char species_buffer[MAX_SPECIES_NAME_LENGTH];
if (fgets(species_buffer, MAX_SPECIES_NAME_LENGTH, f) == NULL) {
free(p);
return NULL;
}
// finish string at '\n' if there is one
char *newline_ptr = strchr(species_buffer, '\n');
if (newline_ptr != NULL) {
*newline_ptr = '\0';
}
// also finish string at '\r' if there is one - files from Windows will
newline_ptr = strchr(species_buffer, '\r');
if (newline_ptr != NULL) {
*newline_ptr = '\0';
}
// malloc a char array long enough to hold species name
// and copy species to it
p->species = malloc(strlen(species_buffer) + 1);
if (p->species == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
strcpy(p->species, species_buffer);
return p;
}
// read a date in year/month/day format from stream f
// return a pointer to a malloced date struct containing them
// return NULL if a date can not be read
struct date *read_date(FILE *f) {
struct date *d = malloc(sizeof (struct date));
if (d == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
int n_scanned = fscanf(f, "%d/%d/%d", &(d->year), &(d->month), &(d->day));
if (n_scanned != 3) {
free(d);
return NULL;
}
return d;
}
void day_whales(struct pod *first_pod, struct date *day) {
day_whale_list.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_SPECIES_NAME_LENGTH 4096
// a struct to represent the date
// a whale pod sighting was made
struct date {
int year;
int month;
int day;
};
// a struct to represent a sighting
// of a pod (group) of whales
struct pod {
struct pod *next;
struct date *when;
int how_many;
char *species;
};
struct pod *read_sightings_file(char filename[]);
struct pod *read_sighting(FILE *f);
struct date *read_date(FILE *f);
struct date *string_to_date(char *s);
void day_whales(struct pod *first_pod, struct date *day);
int same_date(struct date *d1, struct date *d2);
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s <file> <day>\n", argv[0]);
return 1;
}
struct pod *first_pod = read_sightings_file(argv[1]);
struct date *day = string_to_date(argv[2]);
day_whales(first_pod, day);
return 0;
}
// Print the whale sightings, for the specified day.
// One line containing number of whales and species
// is printed for each sighting.
void day_whales(struct pod *first_pod, struct date *day) {
struct pod *p = first_pod;
while (p != NULL) {
if (same_date(p->when, day)) {
printf("%d %s\n", p->how_many, p->species);
}
p = p->next;
}
}
// return1 if 2 dates are the same, 0 otherwise
int same_date(struct date *d1, struct date *d2) {
return d1->year == d2->year &&
d1->month == d2->month &&
d1->day == d2->day;
}
//
// DO NOT CHANGE THE FUNCTIONS BELOW HERE
//
// return linked list of sightings read from filename
// exit called if there is an error
struct pod *read_sightings_file(char filename[]) {
FILE *f = fopen(filename, "r");
if (f == NULL) {
fprintf(stderr,"error: file '%s' can not open\n", filename);
exit(1);
}
struct pod *first_sighting = NULL;
struct pod *last_sighting = NULL;
struct pod *sighting = read_sighting(f);
while (sighting != NULL) {
if (first_sighting == NULL) {
first_sighting = sighting;
first_sighting->next = NULL;
} else {
last_sighting->next = sighting;
}
last_sighting = sighting;
sighting = read_sighting(f);
}
return first_sighting;
}
// read a whale sighting (date, number of whales, whale species)
// return a pointer to a malloced struct containing these details
// return NULL if a sighting can not be read
struct pod *read_sighting(FILE *f) {
struct pod *p = malloc(sizeof (struct pod));
if (p == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
p->next = NULL;
p->when = read_date(f);
if (p->when == NULL) {
free(p);
return NULL;
}
int n_scanned = fscanf(f, "%d", &(p->how_many));
if (n_scanned != 1) {
free(p);
return NULL;
}
fgetc(f);
char species_buffer[MAX_SPECIES_NAME_LENGTH];
if (fgets(species_buffer, MAX_SPECIES_NAME_LENGTH, f) == NULL) {
free(p);
return NULL;
}
// finish string at '\n' if there is one
char *newline_ptr = strchr(species_buffer, '\n');
if (newline_ptr != NULL) {
*newline_ptr = '\0';
}
// also finish string at '\r' if there is one - files from Windows will
newline_ptr = strchr(species_buffer, '\r');
if (newline_ptr != NULL) {
*newline_ptr = '\0';
}
// malloc a char array long enough to hold species name
// and copy species to it
p->species = malloc(strlen(species_buffer) + 1);
if (p->species == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
strcpy(p->species, species_buffer);
return p;
}
// read a date in day/month/year format from stream f
// return a pointer to a malloced date struct containing them
// return NULL if a date can not be read
struct date *read_date(FILE *f) {
struct date *d = malloc(sizeof (struct date));
if (d == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
int n_scanned = fscanf(f, "%d/%d/%d", &(d->day), &(d->month), &(d->year));
if (n_scanned != 3) {
free(d);
return NULL;
}
return d;
}
// given a string containing a date in day/month/year format
// return a pointer to a malloced date struct containing them
// return NULL if a date can not be read
struct date *string_to_date(char *s) {
struct date *d = malloc(sizeof (struct date));
if (d == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
int n_scanned = sscanf(s, "%d/%d/%d", &(d->day), &(d->month), &(d->year));
if (n_scanned != 3) {
free(d);
return NULL;
}
return d;
}
void between_days_whales(struct pod *first_pod, struct date *start_day, struct date *finish_day) {
Note: you can watch a video walkthrough of the solution to Between Days Whales List below.
between_days_whale_list.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_SPECIES_NAME_LENGTH 4096
// a struct to represent the date
// a whale pod sighting was made
struct date {
int year;
int month;
int day;
};
// a struct to represent a sighting
// of a pod (group) of whales
struct pod {
struct pod *next;
struct date *when;
int how_many;
char *species;
};
struct pod *read_sightings_file(char filename[]);
struct pod *read_sighting(FILE *f);
struct date *read_date(FILE *f);
struct date *string_to_date(char *s);
void between_days_whales(struct pod *first_pod, struct date *start_day, struct date *finish_day);
int date_between(struct date *d, struct date *start, struct date *finish);
int date_less_than_equal(struct date *d1, struct date *d2);
void print_sighting(struct pod *s);
void print_date(struct date *d);
int main(int argc, char *argv[]) {
if (argc != 4) {
fprintf(stderr, "Usage: %s <file> <start-day> <finish-day>\n", argv[0]);
return 1;
}
struct pod *first_pod = read_sightings_file(argv[1]);
struct date *start_day = string_to_date(argv[2]);
struct date *finish_day = string_to_date(argv[3]);
between_days_whales(first_pod, start_day, finish_day);
return 0;
}
// Print the whale sightings between start_day and finish_day inclusive.
// One line containing number of whales and species is printed for each sighting.
void between_days_whales(struct pod *first_pod, struct date *start_day, struct date *finish_day) {
struct pod *p = first_pod;
while (p != NULL) {
if (date_between(p->when, start_day, finish_day)) {
print_sighting(p);
}
p = p->next;
}
}
// return 1 if date d is between start and finish inclusive
// return 0 otherwise
int date_between(struct date *d, struct date *start, struct date *finish) {
return date_less_than_equal(start, d) && date_less_than_equal(d, finish);
}
// return 1 if date d1 is before or the same as date d2
// return 0 otherwise
int date_less_than_equal(struct date *d1, struct date *d2) {
return (d1->year < d2->year) ||
(d1->year == d2->year && d1->month < d2->month) ||
(d1->year == d2->year && d1->month == d2->month && d1->day <= d2->day);
}
// print sighting to stdout
void print_sighting(struct pod *p) {
print_date(p->when);
printf(" %2d %s\n", p->how_many, p->species);
}
// print date to stdout
void print_date(struct date *d) {
printf("%02d/%02d/%02d", d->day, d->month, d->year);
}
//
// DO NOT CHANGE THE FUNCTIONS BELOW HERE
//
// return linked list of sightings read from filename
// exit called if there is an error
struct pod *read_sightings_file(char filename[]) {
FILE *f = fopen(filename, "r");
if (f == NULL) {
fprintf(stderr,"error: file '%s' can not open\n", filename);
exit(1);
}
struct pod *first_sighting = NULL;
struct pod *last_sighting = NULL;
struct pod *sighting = read_sighting(f);
while (sighting != NULL) {
if (first_sighting == NULL) {
first_sighting = sighting;
first_sighting->next = NULL;
} else {
last_sighting->next = sighting;
}
last_sighting = sighting;
sighting = read_sighting(f);
}
return first_sighting;
}
// read a whale sighting (date, number of whales, whale species)
// return a pointer to a malloced struct containing these details
// return NULL if a sighting can not be read
struct pod *read_sighting(FILE *f) {
struct pod *p = malloc(sizeof (struct pod));
if (p == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
p->next = NULL;
p->when = read_date(f);
if (p->when == NULL) {
free(p);
return NULL;
}
int n_scanned = fscanf(f, "%d", &(p->how_many));
if (n_scanned != 1) {
free(p);
return NULL;
}
fgetc(f);
char species_buffer[MAX_SPECIES_NAME_LENGTH];
if (fgets(species_buffer, MAX_SPECIES_NAME_LENGTH, f) == NULL) {
free(p);
return NULL;
}
// finish string at '\n' if there is one
char *newline_ptr = strchr(species_buffer, '\n');
if (newline_ptr != NULL) {
*newline_ptr = '\0';
}
// also finish string at '\r' if there is one - files from Windows will
newline_ptr = strchr(species_buffer, '\r');
if (newline_ptr != NULL) {
*newline_ptr = '\0';
}
// malloc a char array long enough to hold species name
// and copy species to it
p->species = malloc(strlen(species_buffer) + 1);
if (p->species == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
strcpy(p->species, species_buffer);
return p;
}
// read a date in day/month/year format from stream f
// return a pointer to a malloced date struct containing them
// return NULL if a date can not be read
struct date *read_date(FILE *f) {
struct date *d = malloc(sizeof (struct date));
if (d == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
int n_scanned = fscanf(f, "%d/%d/%d", &(d->day), &(d->month), &(d->year));
if (n_scanned != 3) {
free(d);
return NULL;
}
return d;
}
// given a string containing a date in day/month/year format
// return a pointer to a malloced date struct containing them
// return NULL if a date can not be read
struct date *string_to_date(char *s) {
struct date *d = malloc(sizeof (struct date));
if (d == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
int n_scanned = sscanf(s, "%d/%d/%d", &(d->day), &(d->month), &(d->year));
if (n_scanned != 3) {
free(d);
return NULL;
}
return d;
}
void merge_day_whales(struct pod *first_pod)
merge_day_whales.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_SPECIES_NAME_LENGTH 4096
// a struct to represent the date
// a whale pod sighting was made
struct date {
int year;
int month;
int day;
};
// a struct to represent a sighting
// of a pod (group) of whales
struct pod {
struct pod *next;
struct date *when;
int how_many;
char *species;
};
struct pod *read_sightings_file(char filename[]);
struct pod *read_sighting(FILE *f);
struct date *read_date(FILE *f);
void write_sightings_file(char filename[], struct pod *first_pod);
void write_sighting(FILE *f, struct pod *p);
void write_date(FILE *f, struct date *d);
void free_sightings(struct pod *p);
void merge_day_whales(struct pod *first_pod);
int same_species_day(struct pod *p1, struct pod *p2);
int same_date(struct date *d1, struct date *d2);
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s <old_file> <new_file>\n", argv[0]);
return 1;
}
struct pod *first_pod = read_sightings_file(argv[1]);
merge_day_whales(first_pod);
write_sightings_file(argv[2], first_pod);
return 0;
}
// merge sightings of the same species on the same day
// into the first sighting of the species on that day
// The number of whales seen in subsequent sightings is added
// to the number of whales seen in the first sighting.
// The subsequent sightings are deleted from the list
// and all associated memory freed.
void merge_day_whales(struct pod *first_pod) {
if (first_pod == NULL) {
return;
}
struct pod *p = first_pod;
while (p->next != NULL) {
struct pod *q = p;
while (q->next != NULL) {
if (same_species_day(p, q->next)) {
p->how_many += q->next->how_many;
struct pod *deleted = q->next;
q->next = q->next->next;
free(deleted->when);
free(deleted->species);
free(deleted);
} else {
q = q->next;
}
}
p = p->next;
}
}
// return 1 if date and species are the same for the sightings, 0 otherwise
int same_species_day(struct pod *p1, struct pod *p2) {
return same_date(p1->when, p2->when) &&
strcmp(p1->species, p2->species) == 0;
}
// return 1 if dates are the same, 0 otherwise
int same_date(struct date *d1, struct date *d2) {
return d1->year == d2->year &&
d1->month == d2->month &&
d1->day == d2->day;
}
//
// DO NOT CHANGE THE FUNCTIONS BELOW HERE
//
// return linked list of sightings read from filename
// exit called if there is an error
struct pod *read_sightings_file(char filename[]) {
FILE *f = fopen(filename, "r");
if (f == NULL) {
fprintf(stderr,"error: file '%s' can not open\n", filename);
exit(1);
}
struct pod *first_sighting = NULL;
struct pod *last_sighting = NULL;
struct pod *sighting = read_sighting(f);
while (sighting != NULL) {
if (first_sighting == NULL) {
first_sighting = sighting;
first_sighting->next = NULL;
} else {
last_sighting->next = sighting;
}
last_sighting = sighting;
sighting = read_sighting(f);
}
return first_sighting;
}
// read a whale sighting (date, number of whales, whale species)
// return a pointer to a malloced struct containing these details
// return NULL if a sighting can not be read
struct pod *read_sighting(FILE *f) {
struct pod *p = malloc(sizeof (struct pod));
if (p == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
p->next = NULL;
p->when = read_date(f);
if (p->when == NULL) {
free(p);
return NULL;
}
int n_scanned = fscanf(f, "%d", &(p->how_many));
if (n_scanned != 1) {
free(p);
return NULL;
}
fgetc(f);
char species_buffer[MAX_SPECIES_NAME_LENGTH];
if (fgets(species_buffer, MAX_SPECIES_NAME_LENGTH, f) == NULL) {
free(p);
return NULL;
}
// finish string at '\n' if there is one
char *newline_ptr = strchr(species_buffer, '\n');
if (newline_ptr != NULL) {
*newline_ptr = '\0';
}
// also finish string at '\r' if there is one - files from Windows will
newline_ptr = strchr(species_buffer, '\r');
if (newline_ptr != NULL) {
*newline_ptr = '\0';
}
// malloc a char array long enough to hold species name
// and copy species to it
p->species = malloc(strlen(species_buffer) + 1);
if (p->species == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
strcpy(p->species, species_buffer);
return p;
}
// read a date in day/month/year format from stream f
// return a pointer to a malloced date struct containing them
// return NULL if a date can not be read
struct date *read_date(FILE *f) {
struct date *d = malloc(sizeof (struct date));
if (d == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
int n_scanned = fscanf(f, "%d/%d/%d", &(d->day), &(d->month), &(d->year));
if (n_scanned != 3) {
free(d);
return NULL;
}
return d;
}
// print linked list of sightings to stream filename
void write_sightings_file(char filename[], struct pod *first_pod) {
FILE *f = fopen(filename, "w");
if (f == NULL) {
fprintf(stderr,"error: file '%s' can not open\n", filename);
exit(1);
}
struct pod *p = first_pod;
while (p != NULL) {
write_sighting(f, p);
p = p->next;
}
}
// print pod details to stream f
void write_sighting(FILE *f, struct pod *p) {
write_date(f, p->when);
fprintf(f, " %2d %s\n", p->how_many, p->species);
}
// print date to stream f
void write_date(FILE *f, struct date *d) {
fprintf(f, "%02d/%02d/%02d", d->day, d->month, d->year);
}
// free the list of sightings
void free_sightings(struct pod *p) {
struct pod *curr = p;
while (curr != NULL) {
struct pod *next = curr->next;
free(curr->species);
free(curr->when);
free(curr);
curr = next;
}
}