简体   繁体   English

Qsort 结构体数组

[英]Qsort array of structs

I have an array of structs that I'm adding entries into我有一个结构数组,我正在向其中添加条目

typedef struct card
{
    char* name;
} card_t;

These are the names in the file: Stolen by the Fae, Eternal Isolation, Corpse Knight, Orzhov Enforcer这些是文件中的名字:被妖精偷走、永恒隔离、尸骑士、欧佐夫执行者

I have a qsort function that is supposed to sort all entries by alphabetical order.我有一个 qsort function 应该按字母顺序对所有条目进行排序。 However it is not working.但是它不起作用。

// FUNCTION FOR QSORT()
int cmpname (const void *pa, const void *pb) {
    const card_t **p1 = pa;
    const card_t **p2 = pb;
    
    return strcmp((*p1(->name, (*p2)->name); 
}
#include "card.h"
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
// FUNCTION FOR QSORT()
int cmpname (const void *pa, const void *pb) {
    const card_t *p1 = pa;
    const card_t *p2 = pb;
    
    return strcmp(p1->name, p2->name); 
}

int main(int argc, char **argv) {   
    char *buf = NULL;
    size_t bufsiz = 0;
    FILE *input_file;
    
    if((input_file = fopen(argv[1], "r")))
    {
        ssize_t result = getline(&buf, &bufsiz, input_file);
        int num_entries = 1;
        card_t **cards = NULL;
    
        int i = 0;
        int cardsaccum = 0;
        int id;
        char *name_duplicate;

        // GETS LINE FROM THE CSV FILE
        result = getline(&buf, &bufsiz, input_file);
        // WHILE THE FILE STILL HAS TEXT
        while (result > 0)
        {   // COPIES BUFFER TO SAVE THE MEMORY ADDRESS
            char *stringp = buf;
            // ALLOCATES MEMORY
            cards = realloc(cards, sizeof(card_t *) * num_entries);
            cards[cardsaccum] = malloc(sizeof(card_t));
            
            cards[cardsaccum]->name = strsep(&stringp, "\"");
            
            cardsaccum++;
            num_entries++;
            // MUST NULL THE BUFFER BEFORE GETLINE 
            buf = NULL;
            // NEXT LINE
            result = getline(&buf, &bufsiz, input_file);
            if(result == -1)
            {
                qsort(cards, cardsaccum - 1, sizeof(student_t *), cmpname);
                //printf("AFTER QSORT \n");
                //printf("\n");
                for(i = 0; i < cardsaccum;i++)
                {
                    printf("%s", cards[i]->name);
                }
            }
        }
        
        for(i=0; i < cardsaccum;i++)
        {
            free(cards[i]);
        }
        free(cards);
        free(buf);
        fclose(input_file);
        return 0;
    }
    else
    {
        fprintf(stderr, "./parser: cannot open(%s%s%s): No such file or directory\n", "\"", argv[1], "\""); 
        return 1;
    }
}

My output is:我的 output 是:

Corpse Knight
Eternal isolation
Stolen by the Fae
Orzhov Enforcer

If I have my qsort function correct, then Stolen by the Fae and Orzhov Enforcer should be switched.如果我的 qsort function 正确,那么应该切换被 Fae 和 Orzhov Enforcer 窃取。 Any suggestions will be greatly appreciated.任何建议将不胜感激。

The other answers about the pointer deferencing are correct.关于指针引用的其他答案是正确的。

However, why are you passing in length-1 instead of the actual number of elements?但是,为什么要传入length-1而不是实际的元素数量?

qsort(cards, cardsaccum - 1, sizeof(char *), cmpname);

Should be:应该:

qsort(cards, cardsaccum, sizeof(cards[0]), cmpname);

The qsort funciton passess pointers to the elements to the comparison function. qsort函数将指向元素的指针传递给比较 function。

In essence it calls your cmpname function like cmpname(&cards[i], &cards[j]) .从本质上讲,它调用你的cmpname function 就像cmpname(&cards[i], &cards[j])

And when every element in the array is a pointer, a pointer to it is a pointer to a pointer.当数组中的每个元素都是指针时,指向它的指针就是指向指针的指针。 Which means the variable p1 and p2 are incorrect in your function, leading to undefined behavior .这意味着变量p1p2在您的 function 中不正确,导致未定义的行为

You need to use the correct types:您需要使用正确的类型:

// FUNCTION FOR QSORT()
int cmpname (const void *pa, const void *pb) {
    const card_t **p1 = pa;  // These are pointer to the elements, and since each
    const card_t **p2 = pb;  // element is a pointer then these becomes pointers to pointers
    
    return strcmp((*p1)->name, (*p2)->name);  // Remember to dereference the pointers
}

You also have some other problems, like the number of elements argument for qsort should really be the number of elements in the array, not the top index.您还有一些其他问题,例如qsort的元素数量参数实际上应该是数组中的元素数量,而不是顶部索引。 And why do you use sizeof(char *) as the element size?为什么使用sizeof(char *)作为元素大小?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM