Search code examples
cstructstring-comparisonvoid-pointersqsort

C: void pointer to struct member of type char[]


I have this class

struct person {
    char name[100];
    int age
};

and then this array:

struct student people[] = { {"bill", 30}, {"john", 20}, {"bob", 11} };

I then want to write a function that I can pass to qsort; a function like this:

int compare_name(const void *a, const void *b);

Normally, when for example having an array of string like this

char names[5][10] = { "xxx", "uuu", "ccc", "aaa", "bbb" };

I would be able to work with the const void * a and const void *b like this:

int compare_name(const void *a, const void *b) {
    for (; *( char*)a == *(char *)b; a++, b++)
        if (*(char *)a == '\0') return 0;
    return *(char *)a - *(char *)b;

But how do I write the same method, that is how do I tell C that the void pointer is referring to the field name of the struct person if I want to sort the array according to alphabetical order?

Eventually, I would need to be able to call qsort like this:

int npeople = sizeof(class) / sizeof(struct student);
qsort(people, npeople, sizeof(struct person), compare_name);

But as said, I am not able to turn const void *a into the needed value (person->name) like I did with *( char*)a when simply working with an array of strings.

Many thanks in advance for your help!


Solution

  • I have this class

     struct person {
         char name[100];
         int age }; 
    

    and then this array:

    struct student people[] = { {"bill", 30}, {"john", 20}, {"bob", 11} };
    

    There are many typos in your code as for example struct person and struct student are different type specifiers. And there are no classes in C opposite to C++.

    Nevertheless the comparison function can look the following way

    #include <string.h>
    
    //...
    
    int compare_name( const void *a, const void *b )
    {
        const struct person *p1 = a;
        const struct person *p2 = b;
    
        return strcmp( p1->name, p2->name );
    } 
    

    Also pay attention to that increment operations like this a++, b++ are not defined for pointers of the type c/v void * though some compilers can have their own language extensions that contradict the C Standard..