orca.c
#include <stdio.h>
#include <string.h>
#define MAX_SPECIES_NAME_LENGTH 128
#define MAX_SIGHTINGS 10000
// 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 date when;
int how_many;
char species[MAX_SPECIES_NAME_LENGTH];
};
int read_sightings_file(char filename[], int len, struct pod sightings[len]);
int read_sighting(FILE *f, struct pod *w);
int read_date(FILE *f, struct date *d);
int count_orca_sightings(int n_sightings, struct pod sightings[n_sightings]);
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <file>\n", argv[0]);
return 1;
}
struct pod whale_sightings[MAX_SIGHTINGS] = {{{0}}};
int n_sightings = read_sightings_file(argv[1], MAX_SIGHTINGS, whale_sightings);
if (n_sightings > 0) {
int n_orca_pods = count_orca_sightings(n_sightings, whale_sightings);
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(int n_sightings, struct pod sightings[n_sightings]) {
int orca_count = 0;
int i = 0;
while (i < n_sightings) {
if (strcmp(sightings[i].species, "Orca") == 0) {
orca_count = orca_count + 1;
}
i = i + 1;
}
return orca_count;
}
//
// DO NOT CHANGE THE FUNCTION BELOW HERE
//
// return number of sightings read from filename
// -1 is returned if there is an error
int read_sightings_file(char filename[], int len, struct pod sightings[len]) {
FILE *f = fopen(filename, "r");
if (f == NULL) {
fprintf(stderr,"error: file '%s' can not open\n", filename);
return -1;
}
int n_sightings = 0;
while (read_sighting(f, &sightings[n_sightings]) == 1 && n_sightings < len) {
n_sightings = n_sightings + 1;
}
fclose(f);
return n_sightings;
}
// return 1 if a sighting can be read, 0 otherwise
int read_sighting(FILE *f, struct pod *s) {
if (read_date(f, &(s->when)) != 1) {
return 0;
}
if (fscanf(f, "%d", &(s->how_many)) != 1) {
return 0;
}
fgetc(f);
if (fgets(s->species, MAX_SPECIES_NAME_LENGTH, f) == NULL) {
return 0;
}
// finish string at '\n' if there is one
char *newline_ptr = strchr(s->species, '\n');
if (newline_ptr != NULL) {
*newline_ptr = '\0';
}
// also finish string at '\r' if there is one - files from Windows will
newline_ptr = strchr(s->species, '\r');
if (newline_ptr != NULL) {
*newline_ptr = '\0';
}
return 1;
}
// return 1 if a date can be read, 0 otherwise
int read_date(FILE *f, struct date *d) {
int n_scanned = fscanf(f, "%d/%d/%d", &(d->year), &(d->month), &(d->day));
return n_scanned == 3;
}
species_count.c
#include <stdio.h>
#include <string.h>
#define MAX_SPECIES_NAME_LENGTH 128
#define MAX_SIGHTINGS 10000
// 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 date when;
int how_many;
char species[MAX_SPECIES_NAME_LENGTH];
};
int read_sightings_file(char filename[], int len, struct pod sightings[len]);
int read_sighting(FILE *f, struct pod *w);
int read_date(FILE *f, struct date *d);
void species_count(char species[], int n_sightings, struct pod sightings[n_sightings],
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 whale_sightings[MAX_SIGHTINGS];
int n_sightings = read_sightings_file(filename, MAX_SIGHTINGS, whale_sightings);
if (n_sightings < 1) {
return 1;
}
int pod_count;
int whale_count;
species_count(species, n_sightings, whale_sightings, &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[], int n_sightings, struct pod sightings[n_sightings],
int *n_pods, int *n_whales) {
int pods = 0;
int whales = 0;
int i = 0;
while (i < n_sightings) {
if (strcmp(sightings[i].species, species) == 0) {
pods = pods + 1;
whales = whales + sightings[i].how_many;
}
i = i + 1;
}
*n_pods = pods;
*n_whales = whales;
}
//
// DO NOT CHANGE THE FUNCTION BELOW HERE
//
// return number of sightings read from filename
// -1 is returned if there is an error
int read_sightings_file(char filename[], int len, struct pod sightings[len]) {
FILE *f = fopen(filename, "r");
if (f == NULL) {
fprintf(stderr,"error: file '%s' can not open\n", filename);
return -1;
}
int n_sightings = 0;
while (read_sighting(f, &sightings[n_sightings]) == 1 && n_sightings < len) {
n_sightings = n_sightings + 1;
}
fclose(f);
return n_sightings;
}
// return 1 if a sighting can be read, 0 otherwise
int read_sighting(FILE *f, struct pod *s) {
if (read_date(f, &(s->when)) != 1) {
return 0;
}
if (fscanf(f, "%d", &(s->how_many)) != 1) {
return 0;
}
fgetc(f);
if (fgets(s->species, MAX_SPECIES_NAME_LENGTH, f) == NULL) {
return 0;
}
// finish string at '\n' if there is one
char *newline_ptr = strchr(s->species, '\n');
if (newline_ptr != NULL) {
*newline_ptr = '\0';
}
// also finish string at '\r' if there is one - files from Windows will
newline_ptr = strchr(s->species, '\r');
if (newline_ptr != NULL) {
*newline_ptr = '\0';
}
return 1;
}
// return 1 if a date can be read, 0 otherwise
int read_date(FILE *f, struct date *d) {
int n_scanned = fscanf(f, "%d/%d/%d", &(d->year), &(d->month), &(d->day));
return n_scanned == 3;
}
whale_summary.c
#include <stdio.h>
#include <string.h>
#define MAX_SPECIES_NAME_LENGTH 128
#define MAX_SIGHTINGS 10000
#define MAX_WHALE_SPECIES 256
// 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 date when;
int how_many;
char species[MAX_SPECIES_NAME_LENGTH];
};
int read_sightings_file(char filename[], int len, struct pod sightings[len]);
int read_sighting(FILE *f, struct pod *w);
int read_date(FILE *f, struct date *d);
void whale_summary(int n_sightings, struct pod sightings[n_sightings]);
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <file> <species>\n", argv[0]);
return 1;
}
struct pod whale_sightings[MAX_SIGHTINGS];
int n_sightings = read_sightings_file(argv[1], MAX_SIGHTINGS, whale_sightings);
if (n_sightings < 1) {
return 1;
}
whale_summary(n_sightings, whale_sightings);
return 0;
}
// a struct to store summary information for each whale species
struct tally {
int pods;
int whales;
char species[MAX_SPECIES_NAME_LENGTH];
};
//
// print a summary of all whale sightings
//
void whale_summary(int n_sightings, struct pod sightings[n_sightings]) {
struct tally summary[MAX_WHALE_SPECIES];
int i = 0;
int n_species_seen = 0;
while (i < n_sightings) {
int j = 0;
char *species = sightings[i].species;
while (j < n_species_seen && strcmp(species, summary[j].species) != 0) {
j = j + 1;
}
if (j < n_species_seen) {
summary[j].pods = summary[j].pods + 1;
summary[j].whales = summary[j].whales + sightings[i].how_many;
} else if (n_species_seen < MAX_WHALE_SPECIES) {
strcpy(summary[n_species_seen].species, species);
summary[n_species_seen].pods = 1;
summary[n_species_seen].whales = sightings[i].how_many;;
n_species_seen = n_species_seen + 1;
} else {
fprintf(stderr, "maximum number of whale species(%d) exceeded\n", MAX_WHALE_SPECIES);
return;
}
i = i + 1;
}
i = 0;
while (i < n_species_seen) {
printf("%d %s pods containing %d whales\n", summary[i].pods, summary[i].species, summary[i].whales);
i = i + 1;
}
}
//
// DO NOT CHANGE THE FUNCTION BELOW HERE
//
// return number of sightings read from filename
// -1 is returned if there is an error
int read_sightings_file(char filename[], int len, struct pod sightings[len]) {
FILE *f = fopen(filename, "r");
if (f == NULL) {
fprintf(stderr,"error: file '%s' can not open\n", filename);
return -1;
}
int n_sightings = 0;
while (read_sighting(f, &sightings[n_sightings]) == 1 && n_sightings < len) {
n_sightings = n_sightings + 1;
}
fclose(f);
return n_sightings;
}
// return 1 if a sighting can be read, 0 otherwise
int read_sighting(FILE *f, struct pod *s) {
if (read_date(f, &(s->when)) != 1) {
return 0;
}
if (fscanf(f, "%d", &(s->how_many)) != 1) {
return 0;
}
fgetc(f);
if (fgets(s->species, MAX_SPECIES_NAME_LENGTH, f) == NULL) {
return 0;
}
// finish string at '\n' if there is one
char *newline_ptr = strchr(s->species, '\n');
if (newline_ptr != NULL) {
*newline_ptr = '\0';
}
// also finish string at '\r' if there is one - files from Windows will
newline_ptr = strchr(s->species, '\r');
if (newline_ptr != NULL) {
*newline_ptr = '\0';
}
return 1;
}
// return 1 if a date can be read, 0 otherwise
int read_date(FILE *f, struct date *d) {
int n_scanned = fscanf(f, "%d/%d/%d", &(d->year), &(d->month), &(d->day));
return n_scanned == 3;
}
sanitize_whales.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#define MAX_SPECIES_NAME_LENGTH 128
#define MAX_SIGHTINGS 10000
#define MAX_WHALE_SPECIES 256
// 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 date when;
int how_many;
char species[MAX_SPECIES_NAME_LENGTH];
};
int read_sightings_file(char filename[], int len, struct pod sightings[len]);
int read_sighting(FILE *f, struct pod *p);
int read_date(FILE *f, struct date *d);
void write_sightings_file(char filename[], int n_sightings, struct pod sightings[n_sightings]);
void write_sighting(FILE *f, struct pod *p);
void write_date(FILE *f, struct date *d);
void sanitize_whales(char species_names_file[], int n_sightings, struct pod sightings[n_sightings]);
void fix_whale_name(char whale_name[], int n_species_names, char correct_whale_names[MAX_WHALE_SPECIES][MAX_SPECIES_NAME_LENGTH]);
int same_whale_name(char whale_name1[], char whale_name2[]);
void canonical_copy(char destination[], char source[]);
int read_species_names(char species_names_file[], char whale_names[MAX_WHALE_SPECIES][MAX_SPECIES_NAME_LENGTH]);
int main(int argc, char *argv[]) {
if (argc != 4) {
fprintf(stderr, "Usage: %s <species_names_file> <old_file> <new_file>\n", argv[0]);
return 1;
}
char *species_names_file = argv[1];
char *old_file = argv[2];
char *new_file = argv[3];
struct pod whale_sightings[MAX_SIGHTINGS];
int n_sightings = read_sightings_file(old_file, MAX_SIGHTINGS, whale_sightings);
if (n_sightings < 1) {
return 1;
}
sanitize_whales(species_names_file, n_sightings, whale_sightings);
write_sightings_file(new_file, n_sightings, whale_sightings);
return 0;
}
//
// sanitize whales remove extra non alphabetic characters
//
void sanitize_whales(char species_names_file[], int n_sightings, struct pod sightings[n_sightings]) {
char correct_whale_names[MAX_WHALE_SPECIES][MAX_SPECIES_NAME_LENGTH];
int n_species_names = read_species_names(species_names_file, correct_whale_names);
int i = 0;
while (i < n_sightings) {
fix_whale_name(sightings[i].species, n_species_names, correct_whale_names);
i = i + 1;
}
}
void fix_whale_name(char whale_name[], int n_species_names, char correct_whale_names[MAX_WHALE_SPECIES][MAX_SPECIES_NAME_LENGTH]) {
int i = 0;
while (i < n_species_names) {
if (same_whale_name(whale_name, correct_whale_names[i])) {
if (strcmp(whale_name, correct_whale_names[i]) != 0) {
strcpy(whale_name, correct_whale_names[i]);
}
return;
}
i = i + 1;
}
assert(0); //whale name not in list
}
//
// return 1 if these are the same whale name
// after ignoring case and non-alphabetic characters
//
int same_whale_name(char whale_name1[], char whale_name2[]) {
char filtered_name1[strlen(whale_name1) + 1];
char filtered_name2[strlen(whale_name2) + 1];
canonical_copy(whale_name1, filtered_name1);
canonical_copy(whale_name2, filtered_name2);
return strcmp(filtered_name1, filtered_name2) == 0;
}
//
// copy alphabetic characters from source to destination
// translating upper case to lower case
//
void canonical_copy(char source[], char destination[]) {
int i = 0;
int j = 0;
while (source[i] != '\0') {
if (isalpha(source[i])) {
destination[j] = tolower(source[i]);
j = j + 1;
}
i = i + 1;
}
destination[j] = '\0';
}
int read_species_names(char species_names_file[], char whale_names[MAX_WHALE_SPECIES][MAX_SPECIES_NAME_LENGTH]) {
FILE *f = fopen(species_names_file, "r");
if (f == NULL) {
fprintf(stderr,"error: file '%s' can not open\n", species_names_file);
exit(1);
}
int n_species_names = 0;
while (fgets(whale_names[n_species_names], MAX_SPECIES_NAME_LENGTH, f) &&
n_species_names < MAX_WHALE_SPECIES) {
char *newline_ptr = strchr(whale_names[n_species_names], '\n');
if (newline_ptr != NULL) {
*newline_ptr = '\0';
}
n_species_names = n_species_names + 1;
}
fclose(f);
return n_species_names;
}
//
// DO NOT CHANGE THE FUNCTION BELOW HERE
//
// return number of sightings read from filename
// -1 is returned if there is an error
int read_sightings_file(char filename[], int len, struct pod sightings[len]) {
FILE *f = fopen(filename, "r");
if (f == NULL) {
fprintf(stderr,"error: file '%s' can not open\n", filename);
return -1;
}
int n_sightings = 0;
while (read_sighting(f, &sightings[n_sightings]) == 1 && n_sightings < len) {
n_sightings = n_sightings + 1;
}
fclose(f);
return n_sightings;
}
// return 1 if a sighting can be read, 0 otherwise
int read_sighting(FILE *f, struct pod *s) {
if (read_date(f, &(s->when)) != 1) {
return 0;
}
if (fscanf(f, "%d", &(s->how_many)) != 1) {
return 0;
}
fgetc(f);
if (fgets(s->species, MAX_SPECIES_NAME_LENGTH, f) == NULL) {
return 0;
}
// finish string at '\n' if there is one
char *newline_ptr = strchr(s->species, '\n');
if (newline_ptr != NULL) {
*newline_ptr = '\0';
}
// also finish string at '\r' if there is one - files from Windows will
newline_ptr = strchr(s->species, '\r');
if (newline_ptr != NULL) {
*newline_ptr = '\0';
}
return 1;
}
// print array of sightings to filename
void write_sightings_file(char filename[], int n_sightings, struct pod sightings[n_sightings]) {
FILE *f = fopen(filename, "w");
if (f == NULL) {
fprintf(stderr,"error: file '%s' can not open\n", filename);
exit(1);
}
int i = 0;
while (i < n_sightings) {
write_sighting(f, &sightings[i]);
i = i + 1;
}
fclose(f);
}
// print pod details to stream f
void write_sighting(FILE *f, struct pod *s) {
write_date(f, &(s->when));
fprintf(f, " %2d %s\n", s->how_many, s->species);
}
// return 1 if a date can be read, 0 otherwise
int read_date(FILE *f, struct date *d) {
int n_scanned = fscanf(f, "%d/%d/%d", &(d->year), &(d->month), &(d->day));
return n_scanned == 3;
}
// print date to stream f
void write_date(FILE *f, struct date *d) {
fprintf(f, "%02d/%02d/%02d", d->year, d->month, d->day);
}