Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//Needs a define for the number of heros in the struct below.
#define MAX_NAME_SIZE 26
struct hero
{
char name[MAX_NAME_SIZE];
char alias[MAX_NAME_SIZE];
int year;
};
void printRecords(struct hero *club);
void sortRecords(char *key, struct hero *club);
int main(int argc, char *argv[])
{
struct hero heroes[] = {
// name alias year
{"Spider-Man", "Peter Parker", 1962},
{"Wonder Woman", "Diana Prince", 1941},
{"Captain America", "Steve Rogers", 1941},
{"Superman", "Clark Kent", 1938},
{"Buffy the Vampire Slayer", "Buffy Summers", 1992},
{"Zorro", "Don Diego de la Vega", 1919},
//{"", "", 0000} //Is this necessary?
};
if (argc == 1) {
printf("Usage: %s sort-key ...\n", argv[0]);
return 1;
}
printf("*** Unsorted:\n");
printRecords(heroes);
for (int i=1; i<argc; i++) { //Problematic. Runs even if there is an error in the argument
char *key = argv[i];
sortRecords(key, heroes);
printf("\n*** Sorted by \"%s\":\n", key); //This needs a check to see if the argument was good or bad.
printRecords(heroes);
}
return 0;
}
// Print the records, with a nice header.
void printRecords(struct hero *club)
{
//Prints the list.
printf("Name Alias Year\n");
for(int i=0; i<6; i++){
printf("%-26s %-26s %-4d\n", club->name, club->alias, club->year);
club = club + 1;
}
}
// Sort the array of records,
// according to the parameter key.
//
// That is, if key is "name", then sort the records
// by the name of the hero: Batman first, Zorro last.
//
// If key is "alias", then sort by the alter ego:
// Buffy Summers is first, Steve Rogers is last.
//
// If key is "year", then sort in DESCENDING ORDER by year.
//
// Anything else, print an error message.
//
// You must use each type of sorting that we discussed in class.
// Three sort keys, three different types of sorting.
void sortRecords(char *key, struct hero *club)
{
struct hero *temphero, *temphero2, temphero3;
//Note: Switch method does not appear to work since GCC says switchs only work with "case labels that reduce to integer constants."
if( strcmp(key, "name") == 0 ){ //Bubble sort for hero names.
//Bubble sort.
int chgcnt = 1; /*A variable for the do while loops to see if any changes have occured when the sort was run. Initialized to 1 for safety.*/
do{
chgcnt = 0;
temphero = club; //Sets the memory address of the club struct to a new temporary hero struct
for( int i=0; i<6; i++){ //Runs for each hero in the hero struct array.
temphero2 = temphero + 1; //Sets a new pointer to one address ahead of the current one for swapping
if(strcmp(temphero->name, temphero2->name) > 0){
temphero3 = *temphero; //Rearranging values
*temphero = *temphero2;
*temphero2 = temphero3;
chgcnt = 1;
}
temphero++;
}
}while(chgcnt != 0);
}
else if( strcmp(key, "alias") == 0){ //Selection Sort for Hero Alias.
//Selection Sort.
int i, j, k = 6; //Ints for for and while loops.
char tempalias[MAX_NAME_SIZE];
struct hero *tempclub, *tempclub2, *tempclub3, temphero;
tempclub = club; //Assigns the same address to temp club as to club.
for( i=0; i<6; i++){ //Runs five times for each sorting hero moved
tempclub2 = tempclub; //(tempclub2) Pointer for the first hero that is yet unsorted
tempclub3 = tempclub; //Sets the temporary value for the lowest unsorted alias to the first hero in the unsorted list.
strcpy(tempalias, tempclub2->alias); //Defaults the first alias to the one with the lowest ascii value.
for( j = 0; j < k; j++){ //Runs for the number of unsorted
tempclub2++;
if( strcmp( tempalias, tempclub2->alias) > 0){ //If the current hero has a lower ascii value in the alias (e.g. the name comes before the on in memory),
//make that new value the next value to be put at the end of the sorted list.
strcpy( tempalias, tempclub2->alias); //Sets the new alias to compare all remaining aliases to
tempclub3 = tempclub2; //Sets the location of the new found lowest alias for the later data swap.
}
}
temphero = *tempclub; // Data from lowest alias dumped to new first and old first moved to position that is now freed up.
*tempclub = *tempclub3;
*tempclub3 = temphero;
tempclub++;
k--; //Reduces the number of unsorted heros.
}
}
else if( strcmp(key, "year") == 0){
//Insertion sort.
int i, j, k, l, m, n; //Tons of ints to run below for and while loops.
struct hero *tempclub, *tempclub2, *tempclub3, temphero, temphero2;
tempclub = club + 1; //Sets the value of the first hero to be sorted to be the second hero in the list (first is by default already inserted).
printf("0:%d, %d\n", club->year, tempclub->year); //Debugging.
for( i=0; i<6; i++){ //Runs for the number of times the sort will run.
tempclub2 = club; //Defaults the beginning of the sorted list to the beginning of the array.
j = 0; //Initializes the constant for the below while loop.
while(j <= i){ //Runs for the number of already sorted numbers.
m = i + 1 - j; //m is a value for the remaining number of heros that have not been compared in the if loop below, that are in the sorted list at the beginning.
if(tempclub-> year > tempclub2->year){ //If the currently selected number is greater than the current position in the sorted list, place it there.
tempclub3 = tempclub2; //Current position in the sorted list. Used to shift heros one over.
temphero = *tempclub;
n = 0;
for( l = 0; l < m; l++){ //Shifts all sorted heros after the current hero being placed, over one position.
tempclub3[n+1] = tempclub3[n];
n++; //The position in the tempclub3 list.
}
*tempclub2 = temphero;
break; //Breaks out of the parent while loop since the values already been sorted.
}
tempclub2++; //Moves to the next sorted hero in the list.
j++; //Increments the counter on the sorted hero list.
}
if( i < 5 ){
tempclub++; //Moves the hero to be sorted over by one since the previous while loop has been completed. Does not need to be run on the fifth time?
}
}
}
else{
printf("\nBad. Unsorted. %s is not a recognized sort method.\n", key);
printf("Usage: Hero [name alias year]\n");
//Bad argument.
}
}
Best Regards,