使用指针对C中的结构数组进行排序

Sorting an array of structs in C with pointers

我的 CIS class 有一个编码作业。作业是编写一个程序,该程序将创建一个结构数组,最多可容纳 10 只狗的信息。在程序结束时,您应该按名称或大小对狗数组进行排序。但是我无法编写狗数组的排序代码。

我想知道如何对 dogs 数组进行排序以供以后在 main 函数中使用。

代码

#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
    }
}

示例输入

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

如有任何帮助,我们将不胜感激!谢谢

在我看来,您的错误在于(尽管我将在下面进行其他评论)将 %c 指定为格式描述符以将指针传递给 int 以进行匹配。您必须传递指向 char 的指针,以使 scanf(3) 到 select 成为放置字符的正确位置。您可能没有得到正确的字符或根本没有字符(这会导致程序中出现未定义的行为)

其他一些问题是当请求按名称排序时(在 n 输入字符上)和其他类似的错误,您正在使用结构的 weight 字段。这包括你在内部循环限制条件中使用 y < (numDogs)(它必须是 y < (numDogs - 1),否则你将比较 y-esim 与 y+1-esim 元素(超出数组边界)

此外,由于您对两个排序选项使用相同的算法,我应该在内循环中包含 switch 语句(您在其中进行比较)否则将迫使您复制相同的排序代码两次(对于整体排序算法),如:

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;
        }
    }
}