0

I have a struct

struct info {
    char firstName[100]; 
    char lastName[100]; 
    char companyName[100];
    char email[100];
    unsigned long phoneNumber; 
}; 

which is stored in the file compareElements.h

I read in a set of values into a dynamically allocated array of structs called bptr.

my comparePtr points to this function.

#include <string.h>
#include "compareElements.h"
int compareNameAscending (const void *a, const void *b) {

    struct info *part1 = (struct info *) a; 
    struct info *part2 = (struct info *) b; 




    if(part1 -> lastName[0] != '\0' && part2 -> lastName[0] != '\0') {
        return (strcmp(part1 -> lastName , part2 -> lastName));
    }   
    if (part1 -> lastName[0] == '\0' && part2 -> lastName[0] != '\0') {
        return (strcmp(part1 -> companyName , part2 -> lastName)); 
    }

    if (part1 -> lastName[0] != '\0' && part2 -> lastName[0] == '\0') {
        return (strcmp(part1 -> lastName, part2 -> companyName)); 
    }

    if (part1 -> lastName[0] == '\0' && part2 -> lastName[0] == '\0') {
        return (strcmp(part1 -> companyName, part2 -> companyName)); 
    } 

}

In the main function I have

comparePtr = &compareNameAscending 

The problem is that not all structs need to have a lastName and companyName only one of the two. So I want to sort by last name, and if they don't have a last name I'll sort by company name. The problem is that my qsort call doesn't ever actually change the order of the struct it just spits out the original. This is the qsort call.

qsort(bptr, i, sizeof(struct info), comparePtr); 
4
  • Show the call that initializes comparePtr. Also, did you get in debug mode and ensured your compare function is actually being called? Commented Apr 2, 2017 at 1:51
  • @Tarik I put it in there Commented Apr 2, 2017 at 2:13
  • Can you reduce the code down to a minimum (removing redundant fields, and blank lines), and show a full example of it failing to sort? Commented Apr 2, 2017 at 2:13
  • There is nothing fundamentally wrong with the code in the question. Your error must be elsewhere. Commented Apr 2, 2017 at 2:26

1 Answer 1

4

I suppose you have problem in initialization of your code, not how to use it, here simplified version of your code that works fine:

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

struct info {
    char lastName[100]; 
    char companyName[100];
}; 

int compareNameAscending (const void *a, const void *b) {

    const struct info *part1 = a; 
    const struct info *part2 = b; 

    const char *s1 = strcmp(part1->lastName, "") == 0 ?
        part1->companyName : part1->lastName;
    const char *s2 = strcmp(part2->lastName, "") == 0 ?
        part2->companyName : part2->lastName;

    return strcmp(s1, s2);
}


int main() {
    struct info bptr[2];
    strcpy(bptr[0].lastName, "");
    strcpy(bptr[0].companyName, "Foo");
    strcpy(bptr[1].lastName, "Boo");
    strcpy(bptr[1].companyName, "");
    qsort(bptr, sizeof(bptr) / sizeof(bptr[0]), sizeof(struct info), compareNameAscending);

    size_t i;
    for (i = 0; i < sizeof(bptr) / sizeof(bptr[0]); ++i) {
        printf("company %s, name %s\n", bptr[i].companyName, bptr[i].lastName);
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

You are missing #include <string.h>, otherwise, works fine.
@DavidC.Rankin actually it is at the begin of code, or you edit my answer?
Oh no, that's fine, it was more of a note than any type of complaint. If whoever is compiling it can't figure it out.... enough said.
In C there is no need to cast here struct info *part1 = (struct info *) a; (same for b).
@alk Thanks, at now I use Rust, so I forgot part of C

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.