Search code examples
carrayssortingstructbubble-sort

Sorting an array of structs in C with pointers


I have a coding assignment for my CIS class. The assignment is to write a program the will create an array of structures that will hold information on at max 10 dogs. At the end of the program, you are supposed to sort the array of dogs by either name or size. But I am unable to code the sorting of the array of dog.

I was wondering how to sort the array of dogs for later use in the main function.

Code

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Dog{
    char name[20];
    int weight;
    int age;
    int ageDogYears;
    char size[7];
};

typedef struct Dog DG;

void calc(DG[], int);
void sort(DG[], int);
void display();

int main(){
    DG dArray[10];
    int x = 0;
    char str[80], *i;

    FILE *inFile;

    inFile = fopen("dogfile.txt", "r");
    if (inFile == NULL){
        printf("Error opening file");
        exit(1);
    }

    while(fgets(str, 80,inFile) != NULL){
        i = strtok(str, ", ");
        strcpy(dArray[x].name, i);
        puts(dArray[x].name);

        i = strtok(NULL, ", ");
        dArray[x].weight = atoi(i);
        printf("%d\n", dArray[x].weight);

        i = strtok(NULL, ", ");
        dArray[x].age = atoi(i);
        printf("%d\n", dArray[x].age);

        x++;
    }

    calc(dArray, x);

    sort(dArray, x);

    return 0;
}

void calc(DG dog[], int numDogs){
    int y, i, total;
    for(i = 0; i < numDogs; ++i){
        if(dog[i].weight <= 20){
            //sets the dog size to small
            strcpy(dog[i].size, "Small");

            for(y = 0; y < dog[i].age; ++y){
                if(y == 0)
                    total += 15;
                else if(y == 1)
                    total += 8;
                else if(y == 2)
                    total += 5;
                else
                    total += 4;
            }
        }
        else if(dog[i].weight <= 50){
            //sets the dog size to medium
            strcpy(dog[i].size, "Medium");

            for(y = 0; y < dog[i].age; ++y){
                if(y == 0)
                    total += 14;
                else if(y == 1)
                    total += 9;
                else if(y == 2)
                    total += 7;
                else
                    total += 5;
            }
        }
        else{
            //sets the dog size to Large
            strcpy(dog[i].size, "Large");

            for(y = 0; y < dog[i].age; ++y){
                if(y == 0)
                    total += 12;
                else if(y == 1)
                    total += 9;
                else if(y == 2)
                    total += 8;
                else
                    total += 7;
            }
        }

        dog[i].ageDogYears = total;
        total = 0;
    }
}

void sort(DG dog[], int numDogs){
    int sortType, i, y, temp;

    printf("\n wlould you like to sort by name(N) or size(S): ");
    scanf("%c", &sortType);

    switch(sortType){
        case 'N': case 'n':
            for(i = 0; i < numDogs; ++i){
                for(y = 0; y < (numDogs); ++y){
                    if(dog[y].weight > dog[y+1].weight){
                        temp = dog[y];
                        dog[y] = dog[y + 1];
                        dog[y + 1] = temp;
                    }
                }
            }
            break;
        default:
            if((sortType != 's') && (sortType != 'S'))
                printf("\n invalid input! Setting sort type to size.");
        //sorting of dog names
    }
}

Sample Input

Fluffy,23,6 Fido,65,7 Pepper,44,5 Bowser,75,10 Victor,10,2 Sassy,51,1

Any help would be much appretated! Thanks.


Solution

  • In my opinion, your error resides (despite of other comments I'll do below) in specifying %c as format descriptor to pass a pointer to int to match. You have to pass a pointer to char to make scanf(3) to select the proper place to put the character into. You probably are not getting the right character or no character at all (this leads to Undefined Behaviour in your program)

    Some other problems are that you are using the weight field of the structure when requested to sort by name (on n input char) and other errors like this. This includes that you use y < (numDogs) in the inner loop limit condition (it must be y < (numDogs - 1), or you'll compare the y-esim with the y+1-esim element (out of array bounds)

    Also, as you are using the same algorithm for both sorting options, I should include the switch statement inside the inner loop (where you do the comparison) as doing otherwise will force you to copy the same sorting code twice (for the overall sorting algorithm), as in:

    for(i = 0; i < numDogs; ++i){
        for(y = 0; y < (numDogs - 1); ++y){
            int sortResultGreater;
            switch (sortType) {
            case 'n': case 'N':
                 sortResultGreater = strcmp(dog[y].name, dog[y+1].name) > 0; 
                 break;
            default: {  /* this should be done as soon as you know the sorting type, not here inside the loop, of course */
                 static int not_already_printed = 1;
                 if (not_already_printed) {
                     printf("Error, sortType must be [nNsS], defaulting to n\n");
                     not_already_printed = 0; /* so we don't get here again */
                 }
            } /* scope of not_already_printed finishes here */
            /* no break used here to fallback to the next case */
            case 's': case 'S':
                 sortResultGreater = dog[y].weight > dog[y+1].weight; 
                 break;
            } /* switch */
            if(sortResultGreater){
                temp = dog[y];
                dog[y] = dog[y + 1];
                dog[y + 1] = temp;
            }
        }
    }